¿Cómo especificar correctamente un valor predeterminado en la anotación Spring @Value?

4 minutos de lectura

Avatar de usuario de Alex
Alex

Inicialmente, tengo la siguiente especificación:

@Value("#{props.isFPL}")
private boolean isFPL=false;

Esto funciona bien obteniendo correctamente el valor del archivo de propiedades:

isFPL = true

Sin embargo, la siguiente expresión con los resultados predeterminados en el error:

@Value("#{props.isFPL:false}")
private boolean isFPL=false;

El análisis de expresiones falló; la excepción anidada es org.springframework.expression.spel.SpelParseException: EL1041E:(pos 28): después de analizar una expresión válida, todavía hay más datos en la expresión: ‘dos ​​puntos (:)’

También traté de usar $ en lugar de #.

@Value("${props.isFPL:true}")
private boolean isFPL=false;

Luego, el valor predeterminado en la anotación funciona bien, pero no obtuve el valor correcto del archivo de propiedades:

  • Con #{} es una expresión, con ${} es un marcador de posición para un valor. La primera expresión que use llamará a un método/atributo en un bean llamado props, la que tiene el marcador de posición intentará ubicar una propiedad llamada props.isFPL en el Environment. Debería usar este último y probablemente esté cargando sus propiedades de manera incorrecta.

    – M. Deinum

    13 de noviembre de 2014 a las 19:18

  • Gracias. Si cargo propiedades de forma incorrecta, ¿por qué #{} toma el valor correcto?

    – Alex

    13 de noviembre de 2014 a las 19:22


  • Porque esa es una expresión, no un marcador de posición. Ambos son evaluados de maneras completamente diferentes.

    – M. Deinum

    13 de noviembre de 2014 a las 19:36

avatar de usuario de shi9
shi9

Prueba con $ como sigue:

@Value("${props.isFPL:true}")
private boolean isFPL=false;

También asegúrese de configurar el ignore-resource-no-found a verdadero de modo que si falta el archivo de propiedades, el por defecto se tomará el valor.

Coloque lo siguiente en el archivo de contexto si usa una configuración basada en XML:

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

Si usa configuraciones de Java:

 @Bean
 public static PropertySourcesPlaceholderConfigurer   propertySourcesPlaceholderConfigurer() {
     PropertySourcesPlaceholderConfigurer p =  new PropertySourcesPlaceholderConfigurer();
     p.setIgnoreResourceNotFound(true);

    return p;
 }

  • Mi problema con $ no es ignorar un valor predeterminado. El problema es que se ignora el valor del archivo de propiedades.

    – Alex

    15 de noviembre de 2014 a las 20:24

  • ¿Cómo estás cargando el archivo de propiedades?

    – shi9

    17 de noviembre de 2014 a las 16:09

Avatar de usuario de Kevin Liu
kevin liu

Para int variable de tipo:

@Value("${my.int.config: #{100}}")
int myIntConfig;

Nota: No hay espacio antes el colon, pero un espacio extra después el colon.

  • No creo que se necesite el espacio adicional (después del colon).

    – Hombre de la sombra

    25 de julio de 2018 a las 21:52

  • Parece una respuesta antigua. Pude mapear el valor int como cualquier otro valor. @Value("${my.int.config:100}")

    – Manish Bansal

    1 oct 2021 a las 14:00

Avatar de usuario de Majid Roustaei
majid roustaei

La respuesta exacta a su pregunta depende de la tipo del parámetro

para los parámetros de ‘Cadena’, su código de muestra funciona bien:

@Value("#{props.string.fpl:test}")
private String fpl = "test";

para otros tipos (como booleano en su pregunta) debe escribirse de esta manera:

@Value("${props.boolean.isFPL:#{false}}")
private boolean isFPL = false;

o para ‘Enteros’:

@Value("${props.integer.fpl:#{20}}")

¿El archivo de contexto de su aplicación Spring contiene más de un bean de marcador de posición de propiedad como se muestra a continuación?

<context:property-placeholder ignore-resource-not-found="true" ignore-unresolvable="true" location="classpath*:/*.local.properties" />
<context:property-placeholder location="classpath:/config.properties" />

Si es así, busque propiedades para: accesorios.isFPL sólo tendrá lugar para el primer archivo de propiedad (.local.properties), si no se encuentra la propiedad, el valor predeterminado (verdadero) tendrá efecto y el segundo archivo de propiedades (config.properties) se ignora efectivamente para esta propiedad.

Para una cadena, puede establecer un valor nulo predeterminado de la siguiente manera:

public UrlTester(@Value("${testUrl:}") String url) {
    this.url = url;
}

  • Desde un punto de vista de mantenimiento, prefiero ver @Value("${testUrl:#{null}}").

    – Betlista

    23 de enero de 2020 a las 2:36

  • Eso parece estar mal. para una cadena ${var:} el valor predeterminado es una cadena vacía ""

    –Peter Wippermann

    11 de enero de 2022 a las 15:09


Avatar de usuario de Mike Summers
mike veranos

Depende de cómo esté cargando sus propiedades, si usa algo como

<context:property-placeholder location="classpath*:META-INF/spring/*.properties" />

Entonces @Value debería verse como

@Value("${isFPL:true}")

  • Desde un punto de vista de mantenimiento, prefiero ver @Value("${testUrl:#{null}}").

    – Betlista

    23 de enero de 2020 a las 2:36

  • Eso parece estar mal. para una cadena ${var:} el valor predeterminado es una cadena vacía ""

    –Peter Wippermann

    11 de enero de 2022 a las 15:09


Avatar de usuario de Kislay Verma
Kislay Verma

Esta forma de definir los valores predeterminados solo funciona si escribimos “value=…” en la anotación @Value. p.ej

No funciona : @Value(“${testUrl:some-url}” // Esto siempre establecerá “some-url” sin importar lo que haga en el archivo de configuración.

Obras : @Value(value = “${testUrl:some-url}” // Esto establecerá “some-url” solo si falta la propiedad testUrl en el archivo de configuración.

¿Ha sido útil esta solución?