使用@PropertySource批注时,@Value未parsing。 如何configurationPropertySourcesPlaceholderConfigurer?

我有以下configuration类:

@Configuration @PropertySource(name = "props", value = "classpath:/app-config.properties") @ComponentScan("service") public class AppConfig { 

我有财产的服务:

 @Component public class SomeService { @Value("#{props['some.property']}") private String someProperty; 

我想要testingAppConfigconfiguration类时收到错误

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String service.SomeService.someProperty; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'props' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' 

这个问题logging在SPR-8539中

但无论如何,我不知道如何configurationPropertySourcesPlaceholderConfigurer让它工作。

编辑1

这种方法适用于xmlconfiguration

 <util:properties id="props" location="classpath:/app-config.properties" /> 

但我想用java进行configuration。

如果您使用@PropertySource,则必须使用以下属性检索属性:

 @Autowired Environment env; // ... String subject = env.getProperty("mail.subject"); 

如果你想用@Value(“$ {mail.subject}”)来检索,你必须用xml注册prop占位符。

原因: https : //jira.springsource.org/browse/SPR-8539

正如@cwash所说;

 @Configuration @PropertySource("classpath:test-config.properties") public class TestConfig { @Value("${name}") public String name; //You need this @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } } 

我发现@value没有为我工作的原因是, @value需要PropertySourcesPlaceholderConfigurer而不是PropertyPlaceholderConfigurer 。 我做了同样的改变,它为我工作,我正在使用spring4.0.3版本。 我在configuration文件中使用下面的代码进行configuration。

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

你不需要一个@Configuration类的方法来返回PropertySourcesPlaceholderConfigurer,注释@Bean,是静态的,用Spring注册任何@PropertySource?

http://www.baeldung.com/2012/02/06/properties-with-spring/#java

https://jira.springsource.org/browse/SPR-8539

我有同样的问题。 @PropertySource@Value@Value 。 一个快速的解决方法是像往常一样使用@ImportResource从XMLconfiguration中引用XMLconfiguration,并且XMLconfiguration文件将包含一个条目: <context:property-placeholder /> (当然,需要的命名空间仪式)。 没有任何其他更改@Value将注入您的@Configuration pojo中的属性。

这也可以这样在java中configuration

 @Bean public static PropertySourcesPlaceholderConfigurer properties() { PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setIgnoreUnresolvablePlaceholders(true); configurer.setIgnoreResourceNotFound(true); return configurer; } 

这看起来很复杂,你不能只是做

  <context:property-placeholder location="classpath:some.properties" ignore-unresolvable="true"/> 

然后在代码参考:

 @Value("${myProperty}") private String myString; @Value("${myProperty.two}") private String myStringTwo; 

some.properties看起来像这样

 myProperty = whatever myProperty.two = something else\ that consists of multiline string 

对于基于java的configuration,你可以做到这一点

 @Configuration @PropertySource(value="classpath:some.properties") public class SomeService { 

然后像以前一样使用@value注入

事情是:据我所知,<util:propertes id =“id”location =“loc”/>,只是一个简写

 <bean id="id" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="location" value="loc"/> </bean> 

(请参阅util:属性的文档 )。 因此,当您使用util:properties时,将创build一个独立的bean。

另一方面,@PropertySource,正如文档所说的是

注释提供了一个方便的声明机制来添加一个PropertySource到Spring的环境。

(请参阅@PropertySource文档 )。 所以它不会创build任何bean。

然后“#{a ['something']}”是一个SpELexpression式(见SpEL ),意思是“从bean获取某个东西”。 当使用util:属性时,bean存在且expression式有意义,但是当使用@PropertySource时,没有实际的bean,expression式是没有意义的。

你可以通过使用XML(这是我认为最好的方法)或者通过自己发布一个PropertiesFactoryBean来解决这个问题,把它声明为普通的@Bean。