18

我在做这个。。

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(context);
xmlReader
        .loadBeanDefinitions(new ClassPathResource("SpringConfig.xml"));
PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
propertyHolder.setLocation(new ClassPathResource(
        "SpringConfig.properties"));
context.addBeanFactoryPostProcessor(propertyHolder);

    ......

context.refresh();

现在在我的@Configuration 文件中,如果我这样做,我的 SpringConfig.properties 中的属性不会被拾取......

@Autowired
private Environment env
.....
env.getProperty("my.property")

但是如果我使用,我会得到那个属性

@Value("${my.property}")
private String myProperty;

我什至尝试添加更多这样的行,但没有用。

ConfigurableEnvironment env = new StandardEnvironment();
propertyHolder.setEnvironment(env);

有人知道为什么我的属性没有加载到环境中吗?谢谢。

4

4 回答 4

16

PropertySourcesPlaceholderConfigurer 直接读取属性文件(就像在 Spring 3.0 中由 PropertyPlaceholderConfigurer 所做的那样),它只是一个后处理器,不会改变在 Spring 上下文中使用属性的方式——在这种情况下,属性只能用作 bean 定义占位符。

使用 Environment 的是 PropertySourcesPlaceholderConfigurer,反之亦然。

属性源框架在应用程序上下文级别上工作,而属性占位符配置器仅提供处理 bean 定义中的占位符的功能。要使用属性源抽象,您应该使用@PropertySource注释,即用类似的东西装饰您的配置类 @PropertySource("classpath:SpringConfig.properties")

我相信您可以以编程方式执行相同的操作,即您可以在刷新上下文之前获取容器的 ConfigurableEnvironment,通过修改其 MutablePropertySources(您需要首先通过 获取AbstractApplicationContext environment属性context.getEnvironment() ),getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource( "SpringConfig.properties")));但您不太可能想要这样做 - 如果您已经有一个带@Configuration注释的类,用它来装饰它@PropertySource("classpath:SpringConfig.properties")要简单得多。

至于PropertySourcesPlaceholderConfigurer实例 - 它会从其应用程序上下文中自动获取属性源(因为它实现了 EnvironmentAware),因此您只需要注册它的默认实例。

有关自定义属性源实现的示例,请参见http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/

于 2013-01-05T08:51:19.257 回答
3

本地属性添加到PropertySourcesPlaceholderConfigurer(with setProperties()or setLocation()) 不会使它们在Environment.

实际上,它以相反的方式工作 -Environment作为属性的主要来源(请参阅 参考资料ConfigurableEnvironment),并且可以使用语法PropertySourcesPlaceholderConfigurer从可用的属性中生成属性。Environment${...}

于 2013-01-05T08:50:51.190 回答
1

我按照@Boris 的建议做了这个..

    PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
    ConfigurableEnvironment env = new StandardEnvironment();
    env.getPropertySources().addFirst(
            new ResourcePropertySource(new ClassPathResource(
                    "SpringConfig.properties")));
    propertyHolder.setEnvironment(env);
    context.addBeanFactoryPostProcessor(propertyHolder);
            context.register(SpringConfig.class);
            context.refresh();

现在在@Configuration 类中,所有属性(包括我自己的和系统属性)都可以使用@Value 解析。

但是将@Autowired 放入@Configuration 类的环境中只有系统属性,而不是我上面设置的SpringConfig.properties。context.refresh()但很明显,在上面调用之前,ConfigurableEnvironment也有我的属性。但是一旦context.refresh()被调用,我的属性就会从自动连接到 @Configuration 的环境中删除。

我希望能够使用更好的语法 env.getProperty("my.property")。有谁知道为什么会这样?

于 2013-01-05T18:59:09.433 回答
0

I am loading 2 types of properties one is the Environment property and the other is the context which you usually get from lets say servletContext.getServletContext(). My environment property is defined as : MOD_CONFIG_ROOT which is set seperately on the environment thereby seperating the location details the ear file which contains code. Here's the configuration. [ Note: I had to load the property files as first thing before loading the servlets to make use of the properties using ${someProperty} ]

<bean id="externalProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>file:#{ systemEnvironment['MOD_CONFIG_ROOT']
                }#{servletContext.contextPath}/users.properties</value>
        </list>
    </property>
    <property name="searchSystemEnvironment" value="true" />
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
</bean>
于 2014-10-24T22:28:29.970 回答