0

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

特别是,我希望能够使用它来设置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.

有可能实现这一目标吗?

4

1 回答 1

3

最简单的解决方案是将环境属性作为命令行参数传递,因此可以将其解析为系统属性。

如果这不是一个选项,您可以实现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. PropertyPlaceholderConfigureraBeanFactoryPostProcessor并调用postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)。这会修改BeanFactory以允许解析属性,例如${my.property:some.default}在设置 bean 的属性时,因为它是由BeanFactory.
  3. SystemPropertyInitializer实现和InitializingBean调用。afterPropertiesSet()此方法在实例化 bean 并设置属性后运行。

所以你是对的,SystemPropertyInitializer因为它在PropertyPlaceholderConfigurer. 但是,将ApplicationContextInitializer能够将这些环境属性提升为系统属性,以便 XML 可以解释它们。

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

 <context:property-placeholder/>

尽管这看起来是多余的,但它可以让您的PropertyPlaceholderConfigurerbean${ENVIRONMENT:hsql}使用您刚刚提升的环境属性来正确评估。

于 2017-03-21T13:09:27.300 回答