2011-01-15 13 views
19

Estoy tratando de utilizar la anotación @Valor en los parámetros de un constructor de la siguiente manera:primavera @Valor anotación no usar por defecto cuando la propiedad no está presente

@Autowired 
public StringEncryptor(
    @Value("${encryptor.password:\"\"}") String password, 
    @Value("${encryptor.algorithm:\"PBEWithMD5AndTripleDES\"}") String algorithm, 
    @Value("${encryptor.poolSize:10}") Integer poolSize, 
    @Value("${encryptor.salt:\"\"}") String salt) { 
... 
} 

Cuando el archivo de propiedades se encuentra presente en la ruta de clases, la las propiedades se cargan perfectamente y la prueba se ejecuta correctamente. Sin embargo, cuando elimino el archivo de propiedades del classpath, esperaba que se hubieran utilizado los valores predeterminados, por ejemplo poolSize se establecería en 10 o algoritmo en PBEWithMD5AndTripleDES, pero este no es el caso.

Ejecutar el código a través de un depurador (que sólo funcionan después de cambiar @Value("${encryptor.poolSize:10}") Integer poolSize a @Value("${encryptor.poolSize:10}") String poolSize ya que estaba causando NumberFormatExceptions) Me parece que los valores predeterminados no se están creando y los parámetros están en la forma de:

poolSize = ${encryptor.poolSize:10} o

algorithm = ${encryptor.algorithm:"PBEWithMD5AndTripleDES"} 

en lugar de la esperada

poolSize = 10 o

algorithm = "PBEWithMD5AndTripleDES" 

Basado en SPR-4785 la notación como $ {my.property:myDefaultValue} debería funcionar. ¡Sin embargo, no me está pasando!

Gracias

Respuesta

22

Tal vez la inicialización del configurador marcador de posición propiedad falla debido a archivo de propiedades perdidas, de manera que los marcadores de posición no se resuelven. Se puede configurar para ignorar los archivos perdidos de la siguiente manera (si se utiliza context espacio de nombres para configurarlo):

<context:property-placeholder ignore-resource-not-found="true" ... /> 

También usted no necesita "..." torno a los valores por defecto.

+0

Exactamente lo que me estaba perdiendo. ¡Gracias! – garyj

+0

... o si usa la configuración basada en anotaciones con 'PropertySourcePlaceholderConfigurer':' propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound (true); ' –

6

ignore-resource-not-found = "true" no es necesario para recuperar los valores predeterminados. El objetivo de especificar el valor predeterminado es que se use si la propiedad no se encuentra en ningún lugar.

Creo que la última oración en la respuesta anterior apunta al problema: EL incorrecto que debe haber proporcionado originalmente pero luego eliminado del ejemplo. El hecho de que estuviera obteniendo excepciones de conversión de formato apunta a eso también. Normalmente, Spring convertirá automáticamente cadenas al tipo de Java "estándar" apropiado, y si proporciona su propia implementación del servicio de conversión de Spring, a sus objetos personalizados también, siempre que su servicio de conversión esté definido en el contexto de la aplicación.

"ignore-resource-not-found" es útil cuando se inyectan propiedades a través de XML sin valores predeterminados y no desea que el contenedor genere una excepción instanciando el bean en caso de que no se encuentre ninguna propiedad. En tales casos, las propiedades del frijol se inicializarán con los valores predeterminados de Java, p. nulls fro objects, 0s para valores numéricos primitivos, etc.

2

En mi caso, la resolución de los valores de propiedad (y los valores predeterminados) no funcionó en la prueba, donde utilizo una configuración basada en anotaciones. Resultó que tenía que agregar un PropertySourcesPlaceholderConfigurer para que las propiedades realmente se resolvieran. Se explicó en el PropertySource Annotation JavaDoc:

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

A continuación se hizo el truco:

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

Y si desea agregar propiedades individuales:

@Bean 
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 

    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); 

    Properties properties = new Properties(); 
    properties.put("batchSize", "250"); 
    propertySourcesPlaceholderConfigurer.setProperties(properties); 

    return propertySourcesPlaceholderConfigurer; 
} 
Cuestiones relacionadas