Spring环境属性源配置

Way*_*neC 12 spring

我正在使用一个名为" Config" 的实用程序类的应用程序库,该实用程序类由Spring Environment对象支持,并为所有应用程序配置值提供强类型的getter.

配置的属性源可能因环境(DEV/PROD)和使用情况(独立/测试/ webapp)而异,范围可以从默认值(system&env props)到自定义数据库和JNDI源.

我正在努力的是如何让使用这个库的应用程序轻松配置所使用的属性源Environment,这样这些属性可以在我们的Config类中使用,也可以通过PropertySourcesPlaceholderConfigurer.

我们仍在使用XML配置,所以理想情况下,这可以用XML配置.

<bean id="propertySources" class="...">
    <property name="sources">
        <list>
            <ref local="jndiPropertySource"/>
            <ref local="databasePropertySource"/>
        </list>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

...然后以某种方式注入到Environment的属性源集合中.

我已经读过,由于应用程序上下文生命周期的时间安排,这样的事情可能无法实现,并且可能需要使用应用程序初始化程序类来完成.

有任何想法吗?

Bij*_*men 11

这取决于你想要如何使用属性,如果是使用${propertyname}语法注入属性,那么只需要使用PropertySourcesPlaceHolderConfigurer就可以工作,它可以在内部访问在环境中注册的PropertySources.

如果您计划直接使用Environment,使用say env.getProperty(),那么您是对的 - 使用PropertySourcesPlaceHolderConfigurer的属性在此处不可见.唯一的方法是使用Java代码注入它,我知道有两种方法:

一个.使用Java Config:

@Configuration
@PropertySource("classpath:/app.properties")
public class SpringConfig{

}
Run Code Online (Sandbox Code Playgroud)

湾 使用自定义ApplicationContextInitializer,这里描述的方式


Way*_*neC 9

我提出了以下似乎有效的方法,但我对Spring很新,所以我不太确定它会在不同的用例中保持不变.

基本上,该方法是扩展PropertySourcesPlaceholderConfigurer和添加一个setter,以允许用户轻松配置PropertySourceXML中的对象List .创建后,属性源将复制到当前Environment.

这基本上允许在一个地方配置属性源,但是由placholder配置和Environment.getProperty场景使用.

扩展 PropertySourcesPlaceholderConfigurer

public class ConfigSourcesConfigurer 
        extends PropertySourcesPlaceholderConfigurer
        implements EnvironmentAware, InitializingBean {

    private Environment environment;
    private List<PropertySource> sourceList;

    // Allow setting property sources as a List for easier XML configuration
    public void setPropertySources(List<PropertySource> propertySources) {

        this.sourceList = propertySources;
        MutablePropertySources sources = new MutablePropertySources();
        copyListToPropertySources(this.sourceList, sources);        
        super.setPropertySources(sources);
    }

    @Override
    public void setEnvironment(Environment environment) {
        // save off Environment for later use
        this.environment = environment;
        super.setEnvironment(environment);
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        // Copy property sources to Environment
        MutablePropertySources envPropSources = ((ConfigurableEnvironment)environment).getPropertySources();
        copyListToPropertySources(this.sourceList, envPropSources);
    }

    private void copyListToPropertySources(List<PropertySource> list, MutablePropertySources sources) {

        // iterate in reverse order to insure ordering in property sources object
        for(int i = list.size() - 1; i >= 0; i--) {
            sources.addFirst(list.get(i));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

beans.xml文件显示基本配置

<beans>
    <context:annotation-config/>
    <context:component-scan base-package="com.mycompany" />

    <bean class="com.mycompany.ConfigSourcesConfigurer">
        <property name="propertySources">
            <list>
                <bean class="org.mycompany.CustomPropertySource" />
                <bean class="org.springframework.core.io.support.ResourcePropertySource">
                    <constructor-arg value="classpath:default-config.properties" />
                </bean>
            </list>
        </property>
    </bean>
    <bean class="com.mycompany.TestBean">
        <property name="stringValue" value="${placeholder}" />
    </bean>
</beans>
Run Code Online (Sandbox Code Playgroud)

  • 您能否举例说明CustomPropertySource的外观? (2认同)

Agu*_*hez 5

以下内容对我来说适用于 Spring 3.2.4 。

PropertySourcesPlaceholderConfigurer必须静态注册才能处理占位符。

自定义属性源在方法中注册init,并且由于默认属性源已经注册,因此它本身可以使用占位符进行参数化。

JavaConfig类:

@Configuration
@PropertySource("classpath:propertiesTest2.properties")
public class TestConfig {

    @Autowired
    private ConfigurableEnvironment env;

    @Value("${param:NOVALUE}")
    private String param;

    @PostConstruct
    public void init() {
        env.getPropertySources().addFirst(new CustomPropertySource(param));
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public TestBean1 testBean1() {
        return new TestBean1();
    }
 }
Run Code Online (Sandbox Code Playgroud)

自定义属性来源:

    public class CustomPropertySource extends PropertySource<Object> {

    public CustomPropertySource(String param) {
        super("custom");
        System.out.println("Custom property source initialized with param " + param + ".");
    }

    @Override
    public Object getProperty(String name) {
        return "IT WORKS";
    }

}
Run Code Online (Sandbox Code Playgroud)

测试bean(getValue()将输出"IT WORKS"):

public class TestBean1 {

   @Value("${value:NOVALUE}")
   private String value;

   public String getValue() {
      return value;
   }
}
Run Code Online (Sandbox Code Playgroud)