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

时间:2022-01-05 12:38:28

I'm currently trying to move an existing spring-application to spring-boot and therefore recreate things that worked without boot.

我目前正在尝试将现有的spring-application移动到spring-boot,因此重新创建无需启动的东西。

I want to configure some properties (like spring.datasource.*) from an external source. specificly a folder with several properties files.

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

I set up a configuration class that creates propertyPlaceholder configurers like this:

我设置了一个配置类来创建propertyPlaceholder配置器,如下所示:

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

This seems to work for most things (like amqp or my own config properties) but when i try to use spring-data-jpa they are ignored. basicly setting spring.datasource.url (and other things used for auto-config) in those files has no effect.

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

looking through the logs of the PropertySourcesPropertyResolver i figured out that these configurer fall under the localProperties group which is not used when looking for spring.datasource.*.

通过查看PropertySourcesPropertyResolver的日志,我发现这些configurer属于localProperties组,在查找spring.datasource。*时未使用。

is there a way to fix this or a better way to add external properties files to my context?

有没有办法解决这个或更好的方法将外部属性文件添加到我的上下文?

I know i could set spring.config.location to do something similar but i can not pass command-line properties to my application and need to do this config from within my application. afaik this is not possible with this property.

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

EDIT: setting spring.config.location:

编辑:设置spring.config.location:

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

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

in both cases the external properties were not picked up at all (even in places where it worked before, like the amqp config)

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

1 个解决方案

#1


How to use external configuration is explained in this section of the Spring Boot Reference Guide.

Spring Boot Reference Guide的“Spring Boot Reference Guide”一节中介绍了如何使用外部配置。

The spring.config.location is a path to the directory which contains your application.properties file. It takes a comma separated list of values so you could specify multiple paths. It doesn't take the wildcard. It is a path so not an expression to match multiple property files. If you want to change the default application then use the spring.config.name to make it something else.

spring.config.location是包含application.properties文件的目录的路径。它采用逗号分隔的值列表,因此您可以指定多个路径。它不需要通配符。它是一个路径,因此不是匹配多个属性文件的表达式。如果要更改默认应用程序,请使用spring.config.name使其成为其他内容。

The defaults of Spring Boot are opinionated as the rest of Spring Boot (with the default configuration etc.).

Spring Boot的默认值与Spring Boot的其余部分(默认配置等)相同。

If you want to do more extensive (pre) configuration you should use an ApplicationContextInitializer to manually add the PropertySources to the Environment. This is mentioned here in the Spring Boot Reference Guide.

如果要进行更广泛的(预)配置,则应使用ApplicationContextInitializer手动将PropertySource添加到Environment。这在Spring Boot Reference Guide中提到。

An example of how the initializer might look.

初始化程序的外观示例。

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

Then when building your application object add it as follows.

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

public class ServletInitializer extends SpringBootServletInitializer {

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

Now the configs should be added to the list of property sources.

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

#1


How to use external configuration is explained in this section of the Spring Boot Reference Guide.

Spring Boot Reference Guide的“Spring Boot Reference Guide”一节中介绍了如何使用外部配置。

The spring.config.location is a path to the directory which contains your application.properties file. It takes a comma separated list of values so you could specify multiple paths. It doesn't take the wildcard. It is a path so not an expression to match multiple property files. If you want to change the default application then use the spring.config.name to make it something else.

spring.config.location是包含application.properties文件的目录的路径。它采用逗号分隔的值列表,因此您可以指定多个路径。它不需要通配符。它是一个路径,因此不是匹配多个属性文件的表达式。如果要更改默认应用程序,请使用spring.config.name使其成为其他内容。

The defaults of Spring Boot are opinionated as the rest of Spring Boot (with the default configuration etc.).

Spring Boot的默认值与Spring Boot的其余部分(默认配置等)相同。

If you want to do more extensive (pre) configuration you should use an ApplicationContextInitializer to manually add the PropertySources to the Environment. This is mentioned here in the Spring Boot Reference Guide.

如果要进行更广泛的(预)配置,则应使用ApplicationContextInitializer手动将PropertySource添加到Environment。这在Spring Boot Reference Guide中提到。

An example of how the initializer might look.

初始化程序的外观示例。

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

Then when building your application object add it as follows.

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

public class ServletInitializer extends SpringBootServletInitializer {

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

Now the configs should be added to the list of property sources.

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