Spring引导:覆盖用于查找application.properties配置文件的约定
我在看spring boot的文档 具体而言,关于财产考虑顺序的章节: 更具体地说: 封装在jar中的特定于配置文件的应用程序属性(应用程序-{Profile}.properties和YAML变体) 首先让我提到,使用这种方法加载特定于概要文件的配置时,我没有遇到任何问题(前提是文件位于classpath:/or classpath:/config中) 然而,我希望做的是实施如下公约:Spring引导:覆盖用于查找application.properties配置文件的约定,spring,spring-boot,Spring,Spring Boot,我在看spring boot的文档 具体而言,关于财产考虑顺序的章节: 更具体地说: 封装在jar中的特定于配置文件的应用程序属性(应用程序-{Profile}.properties和YAML变体) 首先让我提到,使用这种方法加载特定于概要文件的配置时,我没有遇到任何问题(前提是文件位于classpath:/or classpath:/config中) 然而,我希望做的是实施如下公约: classpath:/default/application.properties classpath:/{p
classpath:/default/application.properties
classpath:/{profile}/application.properties
此外,我希望在不使用spring.config.location
属性的情况下实现此配置。我对spring Boot非常陌生,因此我正在寻找一些关于如何实现此约定的提示。根据我的研究,似乎可以通过添加自定义ConfigFileApplicationListener.Ple来实现请让我知道这是否是一个合理的起点或任何其他可能更好的想法
更新:
似乎如果我能够以编程方式构建spring.config.location
属性列表,我可以根据spring.profiles.active环境变量在诸如classpath:/default、classpath:{profile}等位置传递属性。下面的ConfigFileApplicationListener似乎就是我想要调用的:
public void setSearchLocations(String locations)
但是,我不确定在生命周期中我会在哪里打这样的电话。所以我想了一下,不确定我是否会使用这个解决方案,但我想如果有任何有用的反馈,我会提供它 因此,我尝试将调用设置为setSearchLocations(字符串位置)方法在
ConfigFileApplicationListener
上添加到SpringApplication之后,但在其触发之前。我添加了一个新的侦听器,该侦听器也实现了Ordered,并确保它在ConfigFileApplicationListener
之前运行。这似乎是我想要的,但我仍然认为有一个更优雅的ap方法。我特别不喜欢重复听众
public class LocationsSettingConfigFileApplicationListener implements
ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
/**
* this should run before ConfigFileApplicationListener so it can set its
* state accordingly
*/
@Override
public int getOrder() {
return ConfigFileApplicationListener.DEFAULT_ORDER - 1;
}
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
SpringApplication app = event.getSpringApplication();
ConfigurableEnvironment env = event.getEnvironment();
for (ApplicationListener<?> listener : app.getListeners()) {
if (listener instanceof ConfigFileApplicationListener) {
ConfigFileApplicationListener cfal = (ConfigFileApplicationListener) listener;
//getSearchLocations omitted
cfal.setSearchLocations(getSearchLocations(env));
}
}
}
公共类位置设置ConfigFileApplicationListener实现
ApplicationListener,已订购{
/**
*这应该在ConfigFileApplicationListener之前运行,以便可以设置其
*相应地陈述
*/
@凌驾
public int getOrder(){
返回ConfigFileApplicationListener.DEFAULT\u顺序-1;
}
@凌驾
ApplicationEvent上的公共无效(ApplicationEnvironmentPreparedEvent事件){
SpringApplication app=event.getSpringApplication();
ConfigurableEnvironment=event.getEnvironment();
for(ApplicationListener侦听器:app.getListeners()){
if(ConfigFileApplicationListener的侦听器实例){
ConfigFileApplicationListener cfal=(ConfigFileApplicationListener)侦听器;
//省略getSearchLocations
cfal.设置搜索位置(获取搜索位置(环境));
}
}
}
我们对EnvironmentPostProcessor进行了类似的操作,以实现以下命名约定:
setApplicationName
以使用这两个附加文件的应用程序
这里的问题在于我们没有排除默认的ConfigFileApplicationListener
,而是通过删除PropertySourceConfigFileApplicationListener.APPLICATION\u CONFIGURATION\u PROPERTY\u SOURCE\u NAME
来撤销它
文件FooPropertiesEnvPostProcessor.java
为了在测试中获得相同的属性,它们有@ContextConfiguration(…,initializers=TestAppContextInitializer.class)
。
TestAppContextInitializer
实现ApplicationContextInitializer
和调用
FooPropertiesEnvPostProcessor.addProperties
在其initialize
方法中
不幸的是,默认情况下EnvironmentPostProcessor似乎也缺少SpringShell
部分应用程序使用了Spring外壳),这足以限制
在
META-INF/spring/spring shell plugin.xml
中作用域,仅包含不需要EnvironmentPostProcessor设置任何属性的内容。不需要编写新类的解决方案:
# override from outer config , eg. java -jar --spring.profiles.active=your config
spring.profiles.active=dev
spring.config.location=classpath:/${spring.profiles.active}/application.properties
public static void main(String[] args) {
SpringApplication app = new SpringApplication();
app.getListeners().stream()
.filter(listener -> listener instanceof ConfigFileApplicationListener)
.forEach(configListener -> {
((ConfigFileApplicationListener) configListener).setSearchLocations(mySearchLocations);
((ConfigFileApplicationListener) configListener).setSearchNames(mySearchNames);
});
app.setSources(singleton(MyClassName.class));
app.run(args);
}
它似乎无法按您想要的方式进行自定义。我认为您应该覆盖Spring boot github上的
ConfigFileApplicationListener
class或open request。回答时,请回答OP提出的问题。如果发布代码,最好用几句话解释代码的作用。
# override from outer config , eg. java -jar --spring.profiles.active=your config
spring.profiles.active=dev
spring.config.location=classpath:/${spring.profiles.active}/application.properties
public static void main(String[] args) {
SpringApplication app = new SpringApplication();
app.getListeners().stream()
.filter(listener -> listener instanceof ConfigFileApplicationListener)
.forEach(configListener -> {
((ConfigFileApplicationListener) configListener).setSearchLocations(mySearchLocations);
((ConfigFileApplicationListener) configListener).setSearchNames(mySearchNames);
});
app.setSources(singleton(MyClassName.class));
app.run(args);
}