Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring引导:覆盖用于查找application.properties配置文件的约定_Spring_Spring Boot - Fatal编程技术网

Spring引导:覆盖用于查找application.properties配置文件的约定

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

我在看spring boot的文档

具体而言,关于财产考虑顺序的章节:

更具体地说:

封装在jar中的特定于配置文件的应用程序属性(应用程序-{Profile}.properties和YAML变体)

首先让我提到,使用这种方法加载特定于概要文件的配置时,我没有遇到任何问题(前提是文件位于classpath:/or classpath:/config中)

然而,我希望做的是实施如下公约:

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进行了类似的操作,以实现以下命名约定:

  • 系统属性
  • 环境变量
  • “random”(未使用,但我们保留了默认的PropertySource)
  • 文件:${foo.home}/foo-.properties
  • 类路径*:.properties
  • classpath*:application-profile.properties
  • 类路径*:.properties
  • classpath*:application.properties
  • classpath*:meta.properties
  • 有些应用程序没有自己的应用程序;那些在主类的静态初始值设定项中调用
    setApplicationName
    以使用这两个附加文件的应用程序

    这里的问题在于我们没有排除默认的
    ConfigFileApplicationListener
    ,而是通过删除PropertySource
    ConfigFileApplicationListener.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);
    }