gpt4 book ai didi

java - 在设置属性占位符之前使用 SystemPropertyInitializer 设置系统属性

转载 作者:行者123 更新时间:2023-12-02 02:57:02 25 4
gpt4 key购买 nike

根据this answer ,您可以使用 Spring Batch 类 org.springframework.batch.support.SystemPropertyInitializer 在 Spring Context 启动期间设置系统属性。

特别是,我希望能够使用它来设置ENVIRONMENT,因为 Spring Batch 配置的一部分如下:

<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>
<小时/>

由于评论似乎不够充分而添加背景:这是相关的类以及它们被调用/评估的顺序。

  1. ApplicationContextInitializer 告诉 Spring 应用程序如何加载应用程序上下文,并可用于设置 bean 配置文件以及更改上下文的其他方面。这会在上下文完全创建之前执行。
  2. PropertyPlaceholderConfigurer 是一个 BeanFactoryPostProcessor 并调用 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)。这会修改 BeanFactory 以便在设置由 创建的 bean 属性时允许解析诸如 ${my.property:some.default} 之类的属性>BeanFactory
  3. SystemPropertyInitializer 实现 InitializingBean 并调用 afterPropertiesSet()。该方法在 bean 实例化并设置属性后运行。

所以你说得对,SystemPropertyInitializer 在这里没有帮助,因为它在 PropertyPlaceholderConfigurer 上设置属性后进行评估。然而,ApplicationContextInitializer 将能够将这些环境属性提升为系统属性,以便 XML 可以解释它们。

还有一个我忘记提及的注意事项,第一个声明的 bean 之一需要是:

 <context:property-placeholder/>

虽然它看起来多余,但它允许您的 PropertyPlaceholderConfigurer bean 通过使用您刚刚提升的环境属性来正确评估 ${ENVIRONMENT:hsql}

关于java - 在设置属性占位符之前使用 SystemPropertyInitializer 设置系统属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42917939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com