propertysourcesplaceholderconfigurer propertyplaceholderconfigurer example java xml spring configuration

java - example - El archivo Spring @Configuration con el bean PropertyPlaceholderConfigurer no resuelve la anotaciĆ³n @Value



propertyplaceholderconfigurer example (3)

Desde Spring JavaDoc :

Para resolver los marcadores de posición $ {...} en definiciones o anotaciones de @Value utilizando propiedades de un PropertySource, uno debe registrar un PropertySourcesPlaceholderConfigurer. Esto sucede automáticamente cuando se usa en XML, pero se debe registrar explícitamente usando un método estático @Bean cuando se usan las clases de @Configuration. Consulte la sección "Trabajar con valores externalizados" de javadoc de @ Configuration y "una nota sobre los métodos @Bean que devuelven BeanFactoryPostProcessor" de javadoc de @ Bean para obtener detalles y ejemplos.

Por lo tanto, está intentando usar un marcador de posición en el bloque de código requerido para habilitar el procesamiento del marcador de posición.

Como se mencionó en @ M.Deinum, debe usar un PropertySource (implementación predeterminada o personalizada).

El siguiente ejemplo muestra cómo usar las propiedades en una anotación de PropertySource, así como cómo inyectar propiedades de PropertySource en un campo.

@Configuration @PropertySource( value={"classpath:properties/${property:defaultValue}.properties"}, ignoreResourceNotFound = true) public class ConfigExample { @Value("${propertyNameFromFile:defaultValue}") String propertyToBeInjected; /** * Property placeholder configurer needed to process @Value annotations */ @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } }

Tengo el siguiente archivo de configuración:

@Configuration public class PropertyPlaceholderConfigurerConfig { @Value("${property:defaultValue}") private String property; @Bean public static PropertyPlaceholderConfigurer ppc() throws IOException { PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); ppc.setLocations(new ClassPathResource("properties/" + property + ".properties")); ppc.setIgnoreUnresolvablePlaceholders(true); return ppc; } }

Ejecuto mi aplicación con la siguiente opción de VM:

-Dproperty=propertyValue

Así que me gustaría que mi aplicación cargue un archivo de propiedades específico en el inicio. Pero por alguna razón en esta etapa, @Value anotaciones de @Value no se procesan y la propiedad es null . Por otro lado, si tengo PropertyPlaceholderConfigurer configurado a través de un archivo xml, todo funciona perfectamente como se esperaba. Ejemplo de archivo xml:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="ignoreResourceNotFound" value="true"/> <property name="location"> <value>classpath:properties/${property:defaultValue}.properties</value> </property> </bean>

Si intento inyectar valor de propiedad en otro archivo de configuración de Spring, se inyecta correctamente. Si muevo mi creación de bean PropertyPlaceholderConfigurer a ese archivo de configuración, el valor del campo vuelve a ser nulo.

Como solución, utilizo esta línea de código:

System.getProperties().getProperty("property", "defaultValue")

Lo que también funciona, pero me gustaría saber por qué se produce este tipo de comportamiento y tal vez sea posible volver a escribirlo de otra manera pero sin xml.


Para cualquier otra alma pobre que no pueda hacer que esto funcione en algunas clases de Configuración cuando trabaja en otras:

Mira a ver qué otros beans tienes en esa clase y si alguno de ellos se crea una instancia temprana en ApplicationContext. Un servicio de conversión es un ejemplo de uno. Esto crearía una instancia de la clase de Configuración antes de que se registre lo que se requiere, por lo que no se produce ninguna inyección de propiedad.

Solucioné esto moviendo el Servicio de Conversión a otra clase de Configuración que importé.


Si ejecuta su aplicación usando la opción VM y luego desea acceder a esa opción en su aplicación, debe hacerlo de forma ligeramente diferente:

@Value("#{systemProperties.property}") private String property;

Su PropertyPlaceholderConfigurer no tiene conocimiento de las propiedades del sistema, también tenga en cuenta que está accediendo a las propiedades usando $ , que se refiere a los titulares de lugar y # refiere a los beans, donde systemProperties es un bean.