Posso definir nulo como o valor padrão para um @Value na primavera?

99

Atualmente estou usando a anotação @Value Spring 3.1.x assim:

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

Isso coloca uma String vazia na variável se o atributo não estiver presente. Eu gostaria de ter null como padrão em vez de uma String vazia. É claro que também quero evitar um erro quando a propriedade stuff.value não estiver definida.

Kevin Schmidt
fonte

Respostas:

66

Você deve definir o nullValue do PropertyPlaceholderConfigurer . Para o exemplo, estou usando a string, @nullmas você também pode usar a string vazia 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>

Agora você pode usar a string @nullpara representar o nullvalor

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

Observação: o espaço de nome de contexto não suporta o valor nulo no momento. Você não pode usar

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

Testado com Spring 3.1.1

noencéfalo
fonte
2
Qual é a configuração Java equivalente a isso?
Kumar Sambhav
30
stackoverflow.com/questions/9347929/… menciona o uso de $ {some.param: # {null}}, e isso funcionou para mim sem ter que definir nullValue, parece que este é o padrão? (Em um aplicativo Spring Boot.)
vorburger
5
Simplesmente use o poder de SPEL $ {stuff.value: # {null}} conforme sugerido por vorburger e em stackoverflow.com/questions/16735141/…
csf
parece que muito menos configuração é necessária para respostas ben3000 e JRichardsz.
Jeff,
193

Isso é muito antigo, mas você pode usar Spring EL agora, por exemplo

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

Veja esta pergunta .

ben3000
fonte
48

Agradecimentos a @vorburger:

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

irá definir o valor da string em nulo sem quaisquer outras configurações.

Kirill Ch
fonte
3
trabalhou no spring-boot na última versão 2019: 2.1.7.RELEASE ... start.spring.io
JRichardsz 02 de
2

Dou crédito a @nosebrain porque não sabia sobre "valor nulo", mas prefiro evitar o uso de valores nulos, principalmente porque é difícil de representar null em um arquivo de propriedades.

Mas aqui está uma alternativa usando null sem null-valuepara que funcione com qualquer marcador de posição de propriedade.

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;
   }
}

Pessoalmente, eu prefiro do meu jeito porque talvez mais tarde você queira stuff.valueter um valor separado por vírgula ou talvez Enum a troca seja mais fácil. Também é mais fácil testar a unidade :)

EDITAR: com base em seus comentários sobre o uso de enums e minha opinião sobre não usar null.

@Component
public class MyObject {

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

    public enum Crap {
        NOTSET,
        BLAH;
    }
}

O acima funciona bem para mim. Você evita null. Se seus arquivos de propriedades desejam definir explicitamente que eles não querem lidar com isso, você o faz ( mas você nem mesmo precisa especificar isso, pois o padrão será NOTSET ).

crap=NOTSET

nullé muito ruim e é diferente de NOTSET. Isso significa que o teste de primavera ou unidade não definiu, é por isso que há diferença IMHO. Eu provavelmente ainda usaria a notação setter (exemplo anterior) porque é mais fácil de testar a unidade (variáveis ​​privadas são difíceis de definir em um teste de unidade).

Adam Gent
fonte
O valor String era um exemplo, eu realmente precisava disso para um valor Enum, onde uma String vazia apenas causa um erro de conversão. Com o @null você pode ter um nulo como "nenhum conjunto Enum", que é o que eu preciso.
Kevin Schmidt de
Mais uma razão pela qual eu não recomendaria null, mas sim algum enum que represente não definido.
Adam Gent
2
Isso exigiria colocar Enum.NOTSET em todos os arquivos de propriedades (> 30), o que parece muito trabalhoso, quase sem benefícios ...
Kevin Schmidt
Eu não tentei isso, mas em teoria não @Value("${stuff.value:NOTSET}")funcionaria?
Adam Gent de
Sim, esta é uma boa solução. Infelizmente, não posso alterar o enum (dep), então tenho que ir com null. Caso contrário, você está certo, o NOTSET funcionaria.
Kevin Schmidt
0

Caso você precise injetar uma string "" vazia (comprimento 0) como @Value padrão - use SPEL (linguagem de expressão de primavera) da seguinte maneira:

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

# {''} apenas fornece uma string vazia como o padrão do @ Value injetado.

por il

ylev
fonte