¿Puedo establecer nulo como valor predeterminado para un @Value en Spring?

99

Actualmente estoy usando la anotación @Value Spring 3.1.x como esta:

@Value("${stuff.value:}")
private String value;

Esto coloca una Cadena vacía en la variable si el atributo no está presente. Me gustaría tener nulo como valor predeterminado en lugar de una Cadena vacía. Por supuesto, también quiero evitar un error cuando la propiedad stuff.value no está configurada.

Kevin Schmidt
fuente

Respuestas:

66

Debe establecer el nullValue de PropertyPlaceholderConfigurer . Para el ejemplo, estoy usando la cadena, @nullpero también puede usar la cadena vacía como nullValue.

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <!-- config the location(s) of the properties file(s) here -->
    <property name="nullValue" value="@null" />
</bean>

Ahora puedes usar la cadena @nullpara representar el nullvalor.

@Value("${stuff.value:@null}")
private String value;

Tenga en cuenta: el espacio de nombre de contexto no admite el valor nulo en este momento. No puedes usar

<context:property-placeholder null-value="@null" ... />

Probado con Spring 3.1.1

cerebro de nariz
fuente
2
¿Cuál es la configuración de Java equivalente a esto?
Kumar Sambhav
30
stackoverflow.com/questions/9347929/… menciona el uso de $ {some.param: # {null}}, y eso funcionó para mí sin tener que establecer nullValue, ¿parece que este es el valor predeterminado? (En una aplicación Spring Boot.)
vorburger
5
Poder de uso simple de SPEL $ {stuff.value: # {null}} como lo sugiere vorburger y en stackoverflow.com/questions/16735141/…
csf
Parece que se requiere mucha menos configuración para las respuestas ben3000 y JRichardsz.
Jeff
193

Esto es realmente antiguo, pero ahora puedes usar Spring EL, por ejemplo

@Value("${stuff.value:#{null}}")

Vea esta pregunta .

ben3000
fuente
48

Gracias a @vorburger:

@Value("${email.protocol:#{null}}")
String protocol;

establecerá el valor de la cadena en nulo sin ninguna otra configuración.

Kirill Ch
fuente
3
trabajó en spring-boot última versión 2019: 2.1.7.RELEASE ... start.spring.io
JRichardsz
2

Le doy crédito a @nosebrain porque no sabía sobre "valor nulo", pero prefiero evitar el uso de valores nulos por completo, particularmente porque es difícil de representar nullen un archivo de propiedades.

Pero aquí hay una alternativa que usa null sin, null-valuepor lo que funcionará con cualquier marcador de posición de propiedad.

public class MyObject {

   private String value;

   @Value("${stuff.value:@null}")
   public void setValue(String value) {
      if ("@null".equals(value)) this.value = null;
      else this.value = value;
   }
}

Personalmente prefiero mi camino porque tal vez más adelante quieras stuff.valueser un valor separado por comas o tal vez para Enum, el cambio es más fácil. También es más fácil realizar pruebas unitarias :)

EDITAR: basado en sus comentarios sobre el uso de enumeraciones y mi opinión de no usar null.

@Component
public class MyObject {

    @Value("${crap:NOTSET}")
    private Crap crap;

    public enum Crap {
        NOTSET,
        BLAH;
    }
}

Lo anterior funciona bien para mí. Evitas nulo. Si sus archivos de propiedades quieren establecer explícitamente que no quieren manejarlo, entonces lo hace ( pero ni siquiera tiene que especificar esto, ya que estará predeterminado en NOTSET ).

crap=NOTSET

nulles muy malo y es diferente a NOTSET. Significa que la prueba de resorte o de unidad no lo configuró, por lo que en mi humilde opinión hay una diferencia. Probablemente todavía usaría la notación de establecedor (ejemplo anterior) ya que es más fácil de realizar una prueba unitaria (las variables privadas son difíciles de configurar en una prueba unitaria).

Adam Gent
fuente
El valor de String fue un ejemplo, realmente lo necesitaba para un valor de Enum, donde un String vacío solo causa un error de conversión. Con @null puede tener un valor nulo como "sin conjunto Enum", que es lo que necesito.
Kevin Schmidt
Razón de más por la que no recomendaría null sino alguna enumeración que representa no establecida.
Adam Gent
2
Eso requeriría poner Enum.NOTSET en todos los archivos de propiedades (> 30), lo que parece mucho trabajo sin casi beneficios ...
Kevin Schmidt
No he probado esto, pero en teoría no @Value("${stuff.value:NOTSET}")funcionaría.
Adam Gent
Sí, esta es una buena solución. Desafortunadamente, no puedo cambiar la enumeración (dep), así que tengo que ir con null. De lo contrario, tiene razón, el NOTSET funcionaría.
Kevin Schmidt
0

En caso de que necesite inyectar una cadena vacía (longitud 0) "" como @Value predeterminado, use SPEL (lenguaje de expresión de primavera) de la siguiente manera:

@Value("${index.suffix:#{''}}") 
private String indexSuffix;

# {''} solo te da una cadena vacía como la predeterminada de @ Value inyectada.

por yl

ylev
fuente