Spring 3.1 Environment不适用于用户属性文件

我这样做..

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); 

有谁知道为什么我的属性没有加载到Environment中? 谢谢。

PropertySourcesPlaceholderConfigurer直接读取属性文件(因为它是由PropertyPlaceholderConfigurer在Spring 3.0中完成的),它只是一个后处理器,它不会改变Spring上下文中属性的使用方式 – 在这种情况下,属性仅可用作bean定义占位符。

它是使用环境的PropertySourcesPlaceholderConfigurer,反之亦然。

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

我相信您可以通过编程方式执行相同的操作,即您可以在刷新上下文之前获取容器的ConfigurableEnvironment,通过getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource( "SpringConfig.properties")));修改其MutablePropertySources(首先需要通过context.getEnvironment()获取AbstractApplicationContext environment属性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/

PropertySourcesPlaceholderConfigurer添加本地属性(使用setProperties()setLocation() )不会使它们在Environment可用。

实际上它以相反的方式工作 – Environment充当属性的主要来源(请参阅ConfigurableEnvironment ),而PropertySourcesPlaceholderConfigurer可以使用${...}语法使Environment属性可用。

我根据@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”)。 有人知道为什么会这样吗?

我正在加载2种类型的属性,一种是Environment属性,另一种是你通常从中获取的上下文,比如说servletContext.getServletContext() 。 我的环境属性定义为: MOD_CONFIG_ROOT ,它单独设置在环境中,从而将包含代码的ear文件的位置详细信息分开。 这是配置。 [注意:在加载servlet之前我必须首先加载属性文件,以便使用${someProperty} ]来使用属性

    file:#{ systemEnvironment['MOD_CONFIG_ROOT'] }#{servletContext.contextPath}/users.properties