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

时间:2017-10-17 06:46:37

标签: java spring spring-boot properties-file

我有一个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加载属性文件并轻松访问这些值?无法找到有效的解决方案。

我的配置

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

调用配置

@Component
public class TMDbWarper {

@Autowired
private TMDbConfig tmdbConfig;

private TmdbApi tmdbApi;

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

当我自动装备warper时,我在构造函数中遇到NullPointerException。

5 个答案:

答案 0 :(得分:6)

进行现场注射:

在构造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());
    }

<强>(或)

使用@PostConstruct进行初始化,如下所示:

@Component
public class TMDbWarper {

    @Autowired
    private TMDbConfig tmdbConfig;

    private TmdbApi tmdbApi;

    @PostConstruct
    public void init() {
        // any initialisation method
        tmdbConfig.getConfig();
    }

答案 1 :(得分: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;
    }
}

您的其他配置对我来说似乎是对的。

希望这有帮助。

答案 2 :(得分:3)

这是一个Spring Boot多模块示例,您可以在其中获取不同模块中的属性。 假设我有主要应用程序模块, dataparse-module datasave-module。

应用程序模块中的

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

}
resource / config 文件夹中 datasave-module 中的

application.properties

  

datasave.message =多模块Maven项目!

     

threads.xml.number = 5

     

file.location.on.disk = d:\ TEMP \注册表

然后在 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();

    }
}

答案 3 :(得分:1)

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

我做了以下工作以使其正常工作:

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

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

    @Configuration
    @PropertySource("classpath:/com/company/project/application.properties")
    public class AwsConfig
    
  3. 构建并运行,它将像魔术一样工作。

答案 4 :(得分:0)

您可以自动装配并使用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()方法时从上下文中读取属性,无论@Value表达式何时由PropertySourcesPlaceholderConfigurer解析。