Como definir @Value como opcional

119

Eu tenho o seguinte em um bean Spring:

@Value("${myValue}")
private String value;

O valor é injetado corretamente. No entanto, a variável precisa ser opcional, ela é passada como um parâmetro de linha de comando (que é então adicionado ao contexto Spring usando um SimpleCommandLinePropertySource ) e este argumento nem sempre existirá.

Tentei os seguintes procedimentos para fornecer um valor padrão:

@Value("${myValue:}")
@Value("${myValue:DEFAULT}")

mas em cada caso, o argumento padrão após os dois pontos é injetado, mesmo quando há um valor real - parece substituir o que o Spring deve injetar.

Qual é a maneira correta de especificar que @Value não é necessário?

obrigado

user1052610
fonte
Isso é muito estranho ... o valor padrão deve atuar como um valor padrão apenas (ou seja, quando a propriedade não está definida). Você pode verificar novamente sua declaração "o valor padrão é injetado mesmo quando existe um valor real" (por exemplo, se não houver uma classe compilada antiga)?
Pavel Horal
7
@Value("${some.prop:}")funciona para mim. Essa é a única anotação nessa variável.
Zaratustra
Você pode postar a configuração do seu aplicativo?
Vladimir Vagaytsev
@Autowired (obrigatório = falso)?
Andrew Scott Evans

Respostas:

179

Qual é a maneira correta de especificar que @Value não é necessário?

Trabalhando na suposição de que por 'não obrigatório' você quer dizer nullentão ...

Você observou corretamente que pode fornecer um valor padrão à direita de um :caractere. Seu exemplo foi @Value("${myValue:DEFAULT}").

Você não está limitado a strings simples como valores padrão. Você pode usar expressões SPEL , e uma expressão SPEL simples para retornar nullé:

@Value("${myValue:#{null}}")
Andy Brown
fonte
49

Se estiver usando o Java 8, você pode tirar proveito de sua java.util.Optionalclasse. Você só precisa declarar a variável da seguinte maneira:

@Value("${myValue:#{null}}")
private Optional<String> value;

Em seguida, você pode verificar se o valor está definido ou não de uma forma mais agradável:

if (value.isPresent()) {
    // do something cool
}

Espero que ajude!

alonso_50
fonte
4
De acordo com a ideia do IntelliJ. Não é uma prática recomendada usar Optionaltipos em campos de classe.
Fırat KÜÇÜK
2
Você faz isso e lança um NPE. valueé nulo.
aatk
1
@aatk Parece que o problema que você descreve foi corrigido pelo menos desde 4.3.13. Não tenho problemas ao usar a declaração descrita. Embora seja melhor usar apenas um valor anulável: blog.joda.org/2015/08/…
Torben
2
"De acordo com a ideia do IntelliJ. Não é uma prática recomendada usar tipos opcionais em campos de classe." o que há de errado em usar opcional como variável de instância? apenas que tem vida relativamente longa em comparação com quando usado em getters ... e tal campo deve ser marcado como Transiente para serialização?
Andrey M. Stepanov