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

mjj*_*409 4 spring spring-boot

我正在查看位于此处的 spring-boot 文档

具体来说,有关考虑属性的顺序的部分:

进一步来说:

打包在 jar 内的特定于配置文件的应用程序属性(application-{profile}.properties 和 YAML 变体)

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

然而,我希望做的是实现如下所示的约定:

classpath:/default/application.properties
classpath:/{profile}/application.properties
Run Code Online (Sandbox Code Playgroud)

此外,我想在不使用该spring.config.location属性的情况下实现此配置。我对 Spring Boot 还很陌生,所以我正在寻找一些关于如何实现此约定的提示。根据我的研究,这似乎可以通过添加自定义 ConfigFileApplicationListener 来实现。请告诉我这是否是一个合理的起点或任何其他可能更好的想法。

更新:似乎如果我可以以编程方式构建spring.config.location 属性列表,我可以在 classpath:/default、classpath:{profile} 等位置传递。基于 spring.profiles.active 环境变量。以下 ConfigFileApplicationListener 似乎是我想调用的:

public void setSearchLocations(String locations)
Run Code Online (Sandbox Code Playgroud)

但是,我不确定在生命周期的哪个位置进行这样的调用。

mjj*_*409 5

所以这是我设法想出的,不确定我是否会采用这个解决方案,但我想我会提供它以防有任何有用的反馈。

因此,我尝试在将 setSearchLocations(Stringlocations) 方法添加ConfigFileApplicationListener到 SpringApplication 之后但触发之前设置调用。我通过添加一个新的侦听器来做到这一点,该侦听器也实现了 Ordered 并确保它在之前运行ConfigFileApplicationListener。这似乎符合我的要求,但我仍然认为有一种更优雅的方法。我特别不喜欢必须迭代监听器。

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

    }
Run Code Online (Sandbox Code Playgroud)