@Value no resuelto al usar la anotación @PropertySource. ¿Cómo configurar PropertySourcesPlaceholderConfigurer?

Tengo la siguiente clase de configuración:

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

y tengo servicio con propiedad:

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

Recibo un error cuando quiero probar la clase de configuración de AppConfig con

 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' 

El problema está documentado en SPR-8539

pero de todos modos no puedo entender cómo configurar PropertySourcesPlaceholderConfigurer para que funcione.

Editar 1

Este enfoque funciona bien con la configuración xml

  

pero quiero usar Java para la configuración.

Si usa @PropertySource, las propiedades deben recuperarse con:

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

Si desea recuperar con @Value (“$ {mail.subject}”), debe registrar el marcador de posición prop por xml.

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

como dijo @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(); } } 

Encontré que el motivo por el cual @value no funcionaba para mí es que @value requiere PropertySourcesPlaceholderConfigurer lugar de PropertyPlaceholderConfigurer . Hice los mismos cambios y funcionó para mí, estoy usando la versión de spring 4.0.3. Configuré esto usando el código a continuación en mi archivo de configuración.

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

¿No necesita un método en su clase @Configuration que devuelva PropertySourcesPlaceholderConfigurer, anotado @Bean y sea estático, para registrar cualquier @PropertySource con Spring?

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

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

Tuve el mismo problema. @PropertySource no está funcionando bien con @Value . Una solución rápida es tener una configuración XML a la que lo consulte desde su Configuración de Spring Java usando @ImportResource como de costumbre y que el archivo de configuración XML incluirá una sola entrada: (por supuesto con el ceremonia de espacio de nombres necesaria). Sin ningún otro cambio, @Value inyectará propiedades en su @Configuration @Configuration.

Esto también se puede configurar en Java de esta manera

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

Eso se ve muy complicado, ¿no puedes hacer

   

luego en la referencia del código:

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

donde some.properties se parece a esto

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

Para la configuración basada en Java puede hacer esto

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

Y luego solo inyecta usando @value como antes

El caso es que, por lo que yo entiendo, , es solo una abreviatura de

    

(ver documentación de util: propiedades ). Por lo tanto, cuando utiliza util: properties, se crea un bean independiente.

@PropertySource, por otro lado, como la documentación dice es una

anotación que proporciona un mecanismo conveniente y declarativo para agregar un PropertySource al entorno de Spring ‘.

(ver @PropertySource doc ). Por lo tanto, no crea ningún bean.

Entonces “# {a [‘algo’]}” es una expresión SpEL (ver SpEL ), que significa “obtener algo de bean ‘a'”. Cuando util: se usa propiedades, el bean existe y la expresión es significativa, pero cuando se usa @PropertySource, no hay bean real y la expresión no tiene sentido.

Puedes solucionar esto utilizando XML (que es la mejor manera, creo) o emitiendo un PropertiesFactoryBean por ti mismo, declarándolo como un @Bean normal.

Otra cosa que puede estar sucediendo: asegúrese de que sus valores anotados @Value no sean estáticos.