你好!
在本文中,我将向您展示几种如何在Spring Boot项目中添加模块特定的属性文件的方法。 它将介绍使属性文件可识别配置文件的手动方法以及可识别配置文件的半自动方法。 我的Github帐户上发布了一个示例项目( https://github.com/coders-kitchen/spring-boot-multi-module-property-files )。
在多模块项目中每个模块具有专用属性文件的原因有很多。 一种是您希望能够轻松地将模块切成自己的服务。 每个模块都有自己的属性文件,这将对您有所帮助,因为它使用户清楚地知道,他只需要从模块中提取所有文件以使其独立即可。 或者您想为每个模块指定默认值,这些默认值可以被主要属性覆盖。
通常有三种选择
- 通过活动配置文件指定其他属性文件
- 在使用@PropertySource批注的模块中设置配置
- 使Spring上下文了解其他文件模式
让我们一个接一个地讨论:
通过活动配置文件指定的属性文件
这种方法使用Spring的活动配置文件机制来激活其他属性文件。 例如,活动的本地配置文件还将从文件application-local.properties中读取设置。
这种方法的好处是,您只需使用标准机制就可以为每个模块添加新的属性文件。 可以在主application.properties或专用application- <profile> .properties文件中指定它们。
缺点是您必须记住每次都必须以正确的顺序添加活动配置文件,例如,配置文件module1必须在module1-production之前出现,以允许后者覆盖默认配置文件。
另外,您必须记住,默认配置文件需要在所有环境(也称为配置文件)中应用,以使默认设置可用。
通过@PropertySource手册
Spring本身附带了一个注释,用于将其他属性文件添加到上下文中。 它称为@PropertySource ,可以在类级别使用(请参见下一个示例)。
@Configuration
@PropertySource("classpath:application-module1.properties")
public class MyPropertyConfig {}
要使此方法了解多个配置文件,您可以通过以下方式使用它
@Configuration
public class MyPropertyConfig {@Configuration@PropertySource("classpath:application-module1.properties")@Profile("default")static class DefaultConfig {}@Configuration@PropertySource("classpath:application-module1-production.properties")@Profile("production")static class ProductionConfig {}
}
好处是,您不必在主应用程序中为每个模块使用专用的配置文件,而是可以依靠简单的配置文件。 另外,它在配置类本身中表示,这可以很容易地检查哪些配置文件可用。
缺点是,这种方法仅适用于预定义的配置文件集,但是要添加新的配置文件时,必须记住必须将其也添加到MyPropertyConfig类中。 此外,当您更改模块名称时,不仅必须更改文件名,还必须更改代码中的引用。
向属性源添加新的属性文件模式
这种方法是最通用的一种,因为它将直接将新的属性文件模式注入到上下文中,并使其自动识别配置文件。 要使其正常工作,您必须通过ApplicationListener接口使用扩展机制。
这使您可以直接侦听ApplicationEnvironmentPreparedEvent
事件,该事件在准备好运行时环境之后但在加载之前触发。 例如,它使您可以将文件添加到属性源。 该事件提供对ConfigurableEnvironment的访问,该环境可提供有关活动配置文件的信息。
如果侦听器将首先添加特定于配置文件的属性文件,然后将默认属性文件添加到ConfigurableEnvironment ,则这是示例实现。
public class PropertyFilePatternRegisteringListener implements ApplicationListener {public static final String PROPERTY_FILE_PREFIX = "application-module3";private static final String FILE_SUFFIX = ".properties";@Overridepublic void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment environment = event.getEnvironment();try {loadProfileProperties(environment);loadPlainProperties(environment);} catch (IOException ex) {throw new IllegalStateException("Unable to load configuration files", ex);}}private void loadProfileProperties(ConfigurableEnvironment environment) throws IOException {String[] activeProfiles = environment.getActiveProfiles();if(activeProfiles != null && activeProfiles.length > 0)loadProfileProperties(environment, activeProfiles);elseloadProfileProperties(environment, environment.getDefaultProfiles());}private void loadProfileProperties(ConfigurableEnvironment environment, String[] profiles) throws IOException {for (String activeProfile : profiles) {addFileToEnvironment(environment, PROPERTY_FILE_PREFIX + "-" + activeProfile + FILE_SUFFIX);}}private void loadPlainProperties(ConfigurableEnvironment environment) throws IOException {addFileToEnvironment(environment, PROPERTY_FILE_PREFIX + FILE_SUFFIX);}private void addFileToEnvironment(ConfigurableEnvironment environment, String file) throws IOException {ClassPathResource classPathResource = new ClassPathResource(file);if (classPathResource.exists()) {environment.getPropertySources().addLast(new ResourcePropertySource(classPathResource));}}
}
要激活它,您必须在加载应用程序上下文时将其添加为ApplicationListener,如下所示
new SpringApplicationBuilder().listeners(new PropertyFilePatternRegisteringListener()).main(Application.class).registerShutdownHook(true).run(args);}
此变体的好处是,我们与活动配置文件无关,并且可以轻松添加特定于配置文件的新属性文件。 它还在启动过程的早期就启动了,以便应用程序从一开始就意识到此处指定的属性。
缺点是,必须将侦听器添加到每个子模块的主模块中。 而且在测试中使用其他/不同的属性文件(或至少是默认变体)并不是直接的。 在撰写本文时,我仅知道在集成测试中使用@PropertySource可以使其工作。 同样,让它知道默认Spring loader支持的所有情况比上述方法更为复杂。
摘要
在本文中,我们讨论了将新属性文件添加到Spring Boot应用程序的几种方法。 所有变体都有优点和缺点。
根据使用情况,我可以选择@PropertySource或使用ApplicationListener接口。 如果您只想拥有一组通用的属性,可以为特定的配置文件或主要模块的属性覆盖,那么前者就足够了。 当您绝对需要这种灵活性时,应该使用后一种方法。
翻译自: https://www.javacodegeeks.com/2016/11/spring-boot-multi-module-projects-adding-module-specific-property-files.html