Spring 从用户特定文件引导覆盖属性
Spring Boot override properties from a user specific file
我开发的 SpringBoot 应用程序必须 运行 在不同的环境中。 属性 文件已创建,一旦我修改了环境,默认值就会被正确的值覆盖。没关系。
下一步我想检查登录用户 System.getProperty("user.name")
是否有自定义 属性 文件。如果是这样,则必须用他的属性覆盖这些属性。所以步骤应该是(假设活动配置文件是 dev):
- 加载application.properties
- 从应用程序加载和覆盖属性-dev.properties
- 如果用户有自定义 属性 文件 (user.properties),加载它并覆盖属性
我阅读了很多 topcis 并找到了两种可能的解决方案,但其中 none 可行。
- 将注释
@PropertySource("user.properties")
添加到配置 class,这应该加载用户特定的 属性 文件并覆盖值。出于测试目的,我将 server.port=1234
添加到 user.properties,但这被忽略了。
- 创建自定义 PropertyPlaceholderConfigurer。虽然这个bean创建成功,但服务器端口没有改变。
`
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholder() {
PropertyPlaceholderConfigurer propertyPlaceholder = new PropertyPlaceholderConfigurer();
propertyPlaceholder.setLocations(
new ClassPathResource("application.properties"),
new ClassPathResource("application-dev.properties"),
new ClassPathResource("user.properties"));
propertyPlaceholder.setIgnoreResourceNotFound(true);
propertyPlaceholder.setIgnoreUnresolvablePlaceholders(true);
return propertyPlaceholder;
}
我不知道如何前进。所以任何想法都非常受欢迎。
更新: 我刚刚将演示代码推送到 GitHub。也许有助于找到解决方案:https://github.com/aszidien/springboot.
在 Spring 引导中自定义环境的正确方法是使用 EnvironmentPostProcessor
,它将 运行 在 ApplicationContext 启动的早期,并允许您管理 属性来源。
步骤 1. 使用以下内容创建文件 src/main/resources/META-INF/spring.factories
:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.YourEnvironmentPostProcessor
第 2 步。 例如创建一个文件 src/main/resources/custom.properties
包含:
server.port=8081
步骤 3. 现在创建您 post 处理器 class
package com.example;
public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
private final PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
Resource path = new ClassPathResource("custom.properties");
// ^^^ here you can create the resource however you want
// construct the name from a user name, use FileSystemResource, anything
// for example you can ask users to place a file in their home
// directory named "my-application.properties" and load it like so
// Resource path = new FileSystemResource(Paths.get(System.getProperty("user.home"),"my-application.properties").toString());
PropertySource<?> propertySource = loadProps(path);
environment.getPropertySources().addFirst(propertySource);
}
private PropertySource<?> loadProps(Resource path) {
if (!path.exists()) {
throw new IllegalArgumentException("Resource " + path + " does not exist");
}
try {
return this.loader.load("custom-resource", path, null);
}
catch (IOException ex) {
throw new IllegalStateException(
"Failed to load props configuration from " + path, ex);
}
}
}
现在,当您 运行 您的应用程序时,端口将更改为 8081
并且任何其他属性将覆盖主要属性中提供的默认值。
我开发的 SpringBoot 应用程序必须 运行 在不同的环境中。 属性 文件已创建,一旦我修改了环境,默认值就会被正确的值覆盖。没关系。
下一步我想检查登录用户 System.getProperty("user.name")
是否有自定义 属性 文件。如果是这样,则必须用他的属性覆盖这些属性。所以步骤应该是(假设活动配置文件是 dev):
- 加载application.properties
- 从应用程序加载和覆盖属性-dev.properties
- 如果用户有自定义 属性 文件 (user.properties),加载它并覆盖属性
我阅读了很多 topcis 并找到了两种可能的解决方案,但其中 none 可行。
- 将注释
@PropertySource("user.properties")
添加到配置 class,这应该加载用户特定的 属性 文件并覆盖值。出于测试目的,我将server.port=1234
添加到 user.properties,但这被忽略了。 - 创建自定义 PropertyPlaceholderConfigurer。虽然这个bean创建成功,但服务器端口没有改变。
`
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholder() {
PropertyPlaceholderConfigurer propertyPlaceholder = new PropertyPlaceholderConfigurer();
propertyPlaceholder.setLocations(
new ClassPathResource("application.properties"),
new ClassPathResource("application-dev.properties"),
new ClassPathResource("user.properties"));
propertyPlaceholder.setIgnoreResourceNotFound(true);
propertyPlaceholder.setIgnoreUnresolvablePlaceholders(true);
return propertyPlaceholder;
}
我不知道如何前进。所以任何想法都非常受欢迎。
更新: 我刚刚将演示代码推送到 GitHub。也许有助于找到解决方案:https://github.com/aszidien/springboot.
在 Spring 引导中自定义环境的正确方法是使用 EnvironmentPostProcessor
,它将 运行 在 ApplicationContext 启动的早期,并允许您管理 属性来源。
步骤 1. 使用以下内容创建文件 src/main/resources/META-INF/spring.factories
:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.YourEnvironmentPostProcessor
第 2 步。 例如创建一个文件 src/main/resources/custom.properties
包含:
server.port=8081
步骤 3. 现在创建您 post 处理器 class
package com.example;
public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
private final PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
Resource path = new ClassPathResource("custom.properties");
// ^^^ here you can create the resource however you want
// construct the name from a user name, use FileSystemResource, anything
// for example you can ask users to place a file in their home
// directory named "my-application.properties" and load it like so
// Resource path = new FileSystemResource(Paths.get(System.getProperty("user.home"),"my-application.properties").toString());
PropertySource<?> propertySource = loadProps(path);
environment.getPropertySources().addFirst(propertySource);
}
private PropertySource<?> loadProps(Resource path) {
if (!path.exists()) {
throw new IllegalArgumentException("Resource " + path + " does not exist");
}
try {
return this.loader.load("custom-resource", path, null);
}
catch (IOException ex) {
throw new IllegalStateException(
"Failed to load props configuration from " + path, ex);
}
}
}
现在,当您 运行 您的应用程序时,端口将更改为 8081
并且任何其他属性将覆盖主要属性中提供的默认值。