Spring-Boot 多模块项目加载属性文件
Posted
技术标签:
【中文标题】Spring-Boot 多模块项目加载属性文件【英文标题】:Spring-Boot multi module project load property-file 【发布时间】:2018-03-28 18:51:08 【问题描述】:我在 Maven 中有一个 Spring-Boot-Application 作为多模块项目。结构如下:
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。
【问题讨论】:
你能关注这个帖子吗?它也有代码示例。 javacodegeeks.com/2016/11/… 属性文件是否复制到 jar 中?尝试解压缩您的 jar 并检查文件是否存在 好吧,没有更多信息,这只是一个疯狂的猜测,正如 JavaDoc 中所述:为了使用属性解析在对象创建之后(通过反射调用构造函数之后)执行自动装配。所以 NullPointerException
应该在你的构造函数中,因为 tmdbConfig
字段在构造函数调用期间将为空
您可以通过使用@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】:对于现场注入:
在构造 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();
【讨论】:
【参考方案3】:您可以自动装配并使用 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
表达式。
【讨论】:
【参考方案4】:这是一个 Spring Boot 多模块示例,您可以在其中获取不同模块的属性。 假设我有主 application 模块、dataparse-module、datasave-module。
StartApp.java 在 application 模块中:
@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;
application.properties 在 resource/config 文件夹中的 datasave-module 中:
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();
【讨论】:
【参考方案5】:我之前也遇到过这种情况,注意到属性文件没有复制到jar中。
我做了以下工作:
在资源文件夹中,我创建了一个独特的包,然后将我的 application.properties 文件存储在其中。例如:com/company/project
在配置文件中,例如:TMDBConfig.java 我已经引用了我的 .properties 文件的完整路径:
@Configuration
@PropertySource("classpath:/com/company/project/application.properties")
public class AwsConfig
构建并运行,它会像魔术一样工作。
【讨论】:
以上是关于Spring-Boot 多模块项目加载属性文件的主要内容,如果未能解决你的问题,请参考以下文章
多模块 Gradle 项目 - 从 Spring-Boot 1.5 迁移到 2.1