在设置 属性 占位符之前使用 System属性Initializer 设置 System属性
Use of SystemPropertyInitializer to set System Property before setting property placeholder
根据 this answer,您可以使用 Spring 批处理 class org.springframework.batch.support.SystemPropertyInitializer
在 [=30= 启动期间设置系统 属性 ] 上下文。
特别是,我希望能够使用它来设置 ENVIRONMENT
因为 Spring 批处理配置的一部分读取:
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value>
<value>classpath:batch-default.properties</value>
<value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="order" value="1" />
</bean>
但是 SystemPropertyInitializer
使用 afterPropertiesSet()
来设置系统 属性,显然这会发生 在 配置 PropertyPlaceholderConfigurer
之后.
有可能实现吗?
最简单的解决方案是将环境 属性 作为命令行参数传入,因此它可以作为系统 属性.
解析
如果这不是一个选项,您可以实施 ApplicationContextInitializer
将环境属性提升为系统属性。
public class EnvironmentPropertyInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
boolean override = false; //change if you prefer envionment over command line args
@Override
public void initialize(final ConfigurableApplicationContext applicationContext) {
for (Entry<String, String> environmentProp : System.getenv().entrySet()) {
String key = environmentProp.getKey();
if (override || System.getProperty(key) == null) {
System.setProperty(key, environmentProp.getValue());
}
}
}
}
这里看起来您正在使用 Spring Batch Admin,因此您可以通过在 web.xml
文件中添加一些内容来注册您的初始化程序:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>org.your.package.EnvironmentPropertyInitializer</param-value>
</context-param>
添加背景,因为评论似乎不够:这是相关的 类 以及它们的顺序 called/evaluated。
-
ApplicationContextInitializer
告诉 Spring 应用程序如何加载应用程序上下文并可用于设置 bean 配置文件,以及更改上下文的其他方面。这会在 上下文完全创建之前 执行。
PropertyPlaceholderConfigurer
是 BeanFactoryPostProcessor
并调用 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
。当设置由 BeanFactory
. 创建的 bean 的属性时,这会修改 BeanFactory
以允许解析 ${my.property:some.default}
等属性
SystemPropertyInitializer
实现 InitializingBean
并调用 afterPropertiesSet()
。此方法在 bean 实例化并设置属性后运行。
所以你是对的,SystemPropertyInitializer
在这里没有帮助,因为它在 PropertyPlaceholderConfigurer
上设置属性后计算。但是,ApplicationContextInitializer
将能够将这些环境属性提升为系统属性,以便 XML.
可以解释它们
还有一点我忘了提,第一个声明的 bean 需要是:
<context:property-placeholder/>
虽然它看起来多余,但它将允许您的 PropertyPlaceholderConfigurer
bean 通过使用您刚刚提升的环境属性正确评估 ${ENVIRONMENT:hsql}
。
根据 this answer,您可以使用 Spring 批处理 class org.springframework.batch.support.SystemPropertyInitializer
在 [=30= 启动期间设置系统 属性 ] 上下文。
特别是,我希望能够使用它来设置 ENVIRONMENT
因为 Spring 批处理配置的一部分读取:
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value>
<value>classpath:batch-default.properties</value>
<value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="order" value="1" />
</bean>
但是 SystemPropertyInitializer
使用 afterPropertiesSet()
来设置系统 属性,显然这会发生 在 配置 PropertyPlaceholderConfigurer
之后.
有可能实现吗?
最简单的解决方案是将环境 属性 作为命令行参数传入,因此它可以作为系统 属性.
解析如果这不是一个选项,您可以实施 ApplicationContextInitializer
将环境属性提升为系统属性。
public class EnvironmentPropertyInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
boolean override = false; //change if you prefer envionment over command line args
@Override
public void initialize(final ConfigurableApplicationContext applicationContext) {
for (Entry<String, String> environmentProp : System.getenv().entrySet()) {
String key = environmentProp.getKey();
if (override || System.getProperty(key) == null) {
System.setProperty(key, environmentProp.getValue());
}
}
}
}
这里看起来您正在使用 Spring Batch Admin,因此您可以通过在 web.xml
文件中添加一些内容来注册您的初始化程序:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>org.your.package.EnvironmentPropertyInitializer</param-value>
</context-param>
添加背景,因为评论似乎不够:这是相关的 类 以及它们的顺序 called/evaluated。
-
ApplicationContextInitializer
告诉 Spring 应用程序如何加载应用程序上下文并可用于设置 bean 配置文件,以及更改上下文的其他方面。这会在 上下文完全创建之前 执行。 PropertyPlaceholderConfigurer
是BeanFactoryPostProcessor
并调用postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
。当设置由BeanFactory
. 创建的 bean 的属性时,这会修改 SystemPropertyInitializer
实现InitializingBean
并调用afterPropertiesSet()
。此方法在 bean 实例化并设置属性后运行。
BeanFactory
以允许解析 ${my.property:some.default}
等属性
所以你是对的,SystemPropertyInitializer
在这里没有帮助,因为它在 PropertyPlaceholderConfigurer
上设置属性后计算。但是,ApplicationContextInitializer
将能够将这些环境属性提升为系统属性,以便 XML.
还有一点我忘了提,第一个声明的 bean 需要是:
<context:property-placeholder/>
虽然它看起来多余,但它将允许您的 PropertyPlaceholderConfigurer
bean 通过使用您刚刚提升的环境属性正确评估 ${ENVIRONMENT:hsql}
。