Spring-Boot multi module project load property-file

前端 未结 5 1049
面向向阳花
面向向阳花 2021-02-01 18:21

I have a Spring-Boot-Application as a multimodule-Project in maven. The structure is as follows:

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


        
相关标签:
5条回答
  • 2021-02-01 18:55

    I had this situation before, I noticed that the properties file was not copied to the jar.

    I made the following to get it working:

    1. In the resources folder, I have created a unique package, then stored my application.properties file inside it. e.g: com/company/project

    2. In the configuration file e.g: TMDBConfig.java I have referenced the full path of my .properties file:

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

    Build and run, it will work like magic.

    0 讨论(0)
  • 2021-02-01 19:03

    You could autowire and use the Enviornment bean to read the property

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

    This should guarantee that property is read from the context when you invoke the getApiKey() method regardless of when the @Value expression is resolved by PropertySourcesPlaceholderConfigurer.

    0 讨论(0)
  • 2021-02-01 19:05

    Here is a Spring Boot multi-module example where you can get properties in different module. Let's say I have main application module, dataparse-module, datasave-module.

    StartApp.java in application module:

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

    Configuration in dataparse-module. ParseConfig.java:

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

    XmlParseService.java:

    @Service
    public class XmlParseService {...}
    

    Configuration in 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;
        }
    
    }
    

    application.properties in datasave-module in resource/config folder:

    datasave.message=Multi-module Maven project!

    threads.xml.number=5

    file.location.on.disk=D:\temp\registry

    Then in datasave-module you can use all your properties either through @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;
        
        ...
    }
    

    Or through ServiceProperties:

    Service.java:

    @Component
    public class Service {
    
        @Autowired
        ServiceProperties serviceProperties;
    
        public String message() {
    
            return serviceProperties.getMessage();
    
        }
    }
    
    0 讨论(0)
  • 2021-02-01 19:12

    Autowiring is performed just after the creation of the object(after calling the constructor via reflection). So NullPointerException is expected in your constructor as tmdbConfig field would be null during invocation of constructor

    You may fix this by using the @PostConstruct callback method as shown below:

    @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;
        }
    }
    

    Rest of your configuration seems correct to me.

    Hope this helps.

    0 讨论(0)
  • 2021-02-01 19:17

    For field injection:

    Fields are injected right after construction of a bean, before any config methods are invoked. Such a config field does not have to be public. Refer Autowired annotation for complete usage. Use constructor injection in this case like below:

    @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)

    Use @PostConstruct to initialise like below:

    @Component
    public class TMDbWarper {
    
        @Autowired
        private TMDbConfig tmdbConfig;
    
        private TmdbApi tmdbApi;
    
        @PostConstruct
        public void init() {
            // any initialisation method
            tmdbConfig.getConfig();
        }
    
    0 讨论(0)
提交回复
热议问题