如何使用 spring-boot 外部化数据源配置?

How can i externalize datasource configuration with spring-boot?

我目前正在尝试将现有的 spring-应用程序移动到 spring-boot,从而重新创建无需启动即可运行的应用程序。

我想从外部源配置一些属性(如 spring.datasource.*)。特别是一个包含多个属性文件的文件夹。

我设置了一个配置 class 来创建 属性Placeholder 配置器,如下所示:

@Configuration
public class PropertySourceConfiguration {

@Bean
public static PropertySourcesPlaceholderConfigurer defaultsPlaceHolderConfigurer() throws IOException {
    PropertySourcesPlaceholderConfigurer propertyConfigurer = new PropertySourcesPlaceholderConfigurer();
    propertyConfigurer.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/*-defaults.properties"));
    propertyConfigurer.setIgnoreUnresolvablePlaceholders(true);
    return propertyConfigurer;
}

@Bean
public static PropertySourcesPlaceholderConfigurer externalPlaceHolderConfigurer() throws IOException {
    PropertySourcesPlaceholderConfigurer propertyConfigurer = new PropertySourcesPlaceholderConfigurer();
    propertyConfigurer.setLocations(new
            PathMatchingResourcePatternResolver().getResources("file:/my-config-path/*.properties"));
    propertyConfigurer.setOrder(1);
    propertyConfigurer.setIgnoreUnresolvablePlaceholders(true);
    return propertyConfigurer;
}

这似乎适用于大多数事情(比如 amqp 或我自己的配置属性),但是当我尝试使用 spring-data-jpa 时,它们会被忽略。基本上在这些文件中设置 spring.datasource.url(以及其他用于自动配置的东西)没有效果。

查看 PropertySourcesPropertyResolver 的日志,我发现这些配置器属于 localProperties 组,在查找 spring.datasource.*.

时不使用该组

是否有解决此问题的方法或将外部属性文件添加到我的上下文的更好方法?

我知道我可以设置 spring.config.location 来做类似的事情,但我无法将命令行属性传递给我的应用程序,需要在我的应用程序中进行此配置。 afaik 这是不可能的 属性.

编辑: 设置 spring.config.location

尝试 1:

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(CampaignServiceStarter.class);
    }
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        servletContext.setInitParameter("spring.config.location", "file:/my-config-path/*.properties");
    }
}

尝试 2:

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(CampaignServiceStarter.class).properties("spring.config.location=file:/my-config-path/*.properties");
    }
}

在这两种情况下,根本没有提取外部属性(即使在它之前工作的地方,比如 amqp 配置)

Spring 引导参考指南的 this section 中解释了如何使用外部配置。

spring.config.location 是包含您的 application.properties 文件的目录的路径。它采用逗号分隔的值列表,因此您可以指定多个路径。它不需要通配符。它是一个路径,而不是匹配多个 属性 文件的表达式。如果你想改变默认的 application 那么使用 spring.config.name 来改变它。

Spring Boot 的默认设置与 Spring Boot 的其余部分一样(使用默认配置等)。

如果您想进行更广泛的(预)配置,您应该使用 ApplicationContextInitializer 手动将 PropertySource 添加到 Environment。 Spring 引导参考指南中提到了 here

初始值设定项的外观示例。

public class ConfigurationInitializer implements ApplicationContextInitializer {

    private static final String DEFAULT_PROPS = "classpath*:/*-defaults.properties";
    private static final String EXTERNAL_PROPS = "file:/my-config-path/*.properties";

    public void initialize(ConfigurableApplicationContext applicationContext) {
        final Resource[] defaultConfigs = applicationContext.getResources(DEFAULT_PROPS);
        final Resource[] externalConfigs = applicationContext.getResources(EXTERNAL_PROPS);

        final ConfigurableEnvironment env = applicationContext.getEnvironment();
        final MutablePropertySources mps =  env.getPropertySources();
        for (Resource r : externalConfigs) {
            mps.addLast(new ResourcePropertySource(r.getFilename(), r);
        }
        for (Resource r : defaultConfigs) {
            mps.addLast(new ResourcePropertySource(r.getFilename(), r);
        }   
    }
}

然后在构建应用程序对象时按如下方式添加它。

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(CampaignServiceStarter.class)
            .initializers(new ConfigurationInitializer());
    }
}

现在应该将配置添加到 属性 源列表中。