首页 文章

Spring-Boot多模块项目加载属性文件

提问于
浏览
16

我有一个Spring-Boot-Application作为maven中的multimodule-Project . 结构如下:

Parent-Project
|--MainApplication
|--Module1
|--ModuleN

MainApplication 项目中, main() 方法类用 @SpringBootApplication 注释,依此类推 . 此项目一如既往地自动加载application.properties文件 . 所以我可以使用 @Value 注释访问这些值

@Value("${myapp.api-key}")
private String apiKey;

在我的Module1中,我也想使用属性文件(称为module1.properties),其中存储了模块配置 . 只能在模块中访问和使用此文件 . 但是我无法加载它 . 我用 @Configuration@PropertySource 尝试过但没有运气 .

@Configuration
@PropertySource(value = "classpath:module1.properties")
public class ConfigClass {

如何使用Spring-Boot加载属性文件并轻松访问这些值?找不到有效的解决方案 .

My Configuration

@Configuration
@PropertySource(value = "classpath:tmdb.properties")
public class TMDbConfig {

    @Value("${moviedb.tmdb.api-key}")
    private String apiKey;

    public String getApiKey() {
        return apiKey;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

Calling the Config

@Component
public class TMDbWarper {

@Autowired
private TMDbConfig tmdbConfig;

private TmdbApi tmdbApi;

public TMDbWarper(){
    tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
}

当我自动装备warper时,我在构造函数中得到一个NullPointerException .

5 回答

  • 0

    For field injection:

    在调用任何配置方法之前,在构造bean之后立即注入字段 . 这样的配置字段不必是公共的 . 有关完整用法,请参阅Autowired annotation . 在这种情况下使用构造函数注入,如下所示:

    @Component
    public class TMDbWarper {
    
        private TMDbConfig tmdbConfig;
    
        private TmdbApi tmdbApi;
    
        @Autowired
        public TMDbWarper(final TMDbConfig tmdbConfig){
                this.tmdbConfig = tmdbConfig;
                tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
        }
    

    (or)

    使用 @PostConstruct 初始化如下:

    @Component
    public class TMDbWarper {
    
        @Autowired
        private TMDbConfig tmdbConfig;
    
        private TmdbApi tmdbApi;
    
        @PostConstruct
        public void init() {
            // any initialisation method
            tmdbConfig.getConfig();
        }
    
  • 5

    在创建对象之后执行自动装配(在通过反射调用构造函数之后) . 所以 NullPointerException 在构造函数中是预期的,因为 tmdbConfig 字段在构造函数的调用期间将为null

    您可以使用@PostConstruct回调方法解决此问题,如下所示:

    @Component
    public class TMDbWarper {
    
        @Autowired
        private TMDbConfig tmdbConfig;
    
        private TmdbApi tmdbApi;
    
        public TMDbWarper() {
    
        }
    
        @PostConstruct
        public void init() {
            tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
        }
    
        public TmdbApi getTmdbApi() {
            return this.tmdbApi;
        }
    }
    

    其余的配置似乎对我来说是正确的 .

    希望这可以帮助 .

  • 3

    这是一个Spring Boot多模块示例,您可以在其中获取不同模块中的属性 . 假设我有主 application 模块, dataparse-moduledatasave-module.

    application 模块中的StartApp.java:

    @SpringBootApplication
    public class StartApp {
    
        public static void main(String[] args) {
    
            SpringApplication.run(StartApp.class, args);
        }
    }
    

    dataparse-module 中的配置 . ParseConfig.java:

    @Configuration
    public class ParseConfig {
            @Bean
            public XmlParseService xmlParseService() {
                return new XmlParseService();
            }
    }
    

    XmlParseService.java:

    @Service
    public class XmlParseService {...}
    

    datasave-module 中的配置 . SaveConfig.java:

    @Configuration
    @EnableConfigurationProperties(ServiceProperties.class)
    @Import(ParseConfig.class)//get beans from dataparse-module - in this case XmlParseService
    public class SaveConfig {
    
        @Bean
        public SaveXmlService saveXmlService() {
            return new SaveXmlService();
    
        }
    
    }
    

    ServiceProperties.java:

    @ConfigurationProperties("datasave")
    public class ServiceProperties {
    
        private String message;
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
    }
    

    资源/配置文件夹中 datasave-module 中的application.properties:

    datasave.message =多模块Maven项目! threads.xml.number = 5 file.location.on.disk = D:\ temp \ registry

    然后在 datasave-module 中,您可以通过@Value使用所有属性 .

    SaveXmlService.java:

    @Service
    public class SaveXmlService {
    
        @Autowired
        XmlParseService xmlParseService;
    
        @Value("${file.location.on.disk: none}")
        private String fileLocation;
    
        @Value("${threads.xml.number: 3}")
        private int numberOfXmlThreads;
    
        ...
    }
    

    或者通过ServiceProperties:

    Service.java:

    @Component
    public class Service {
    
        @Autowired
        ServiceProperties serviceProperties;
    
        public String message() {
    
            return serviceProperties.getMessage();
    
        }
    }
    
  • 1

    我之前遇到过这种情况,我注意到属性文件没有复制到jar中 .

    我做了以下工作让它工作:

    • 在resources文件夹中,我创建了一个唯一的包,然后将application.properties文件存储在其中 . 例如:com / company / project

    • 在配置文件中,例如:TMDBConfig.java我引用了.properties文件的完整路径:

    @Configuration
    @PropertySource("classpath:/com/company/project/application.properties")
    public class AwsConfig
    

    构建和运行,它将像魔术一样工作 .

  • 6

    您可以自动装配并使用Enviornment bean来读取属性

    @Configuration
    @PropertySource(value = "classpath:tmdb.properties")
    public class TMDbConfig {
    
      @Autowired
      private Environment env;
    
      public String getApiKey() {
        return env.getRequiredProperty("moviedb.tmdb.api-key");
      }
    
    }
    

    这应该保证在调用 getApiKey() 方法时从上下文中读取属性,而不管 PropertySourcesPlaceholderConfigurer 解析 @Value 表达式的时间 .

相关问题