Тонкости использования аннотации @Value в Spring Boot

Аннотация @Value - это самый простой способ для “впрыскивания” значений из конфигурации Spring Boot в код. При этом также можно задать значение по-умолчанию.

Однако, стоит учитывать, что резолвинг значения будет выполняться для каждой аннотации @Value. Например, если аннотировать @Value два поля (в одном или разных классах - не суть важно) вот так:

@Value("${unique-param}")
private String param1;

@Value("${unique-param}")
private String param2;

, то в debug-логе мы увидим:

TRACE 23601 --- [lication.main()] o.s.c.e.PropertySourcesPropertyResolver  : getProperty("unique-param", String)
DEBUG 23601 --- [lication.main()] o.s.c.e.PropertySourcesPropertyResolver  : Searching for key 'unique-param' in [environmentProperties]
...
TRACE 23601 --- [lication.main()] o.s.c.e.PropertySourcesPropertyResolver  : getProperty("unique-param", String)
DEBUG 23601 --- [lication.main()] o.s.c.e.PropertySourcesPropertyResolver  : Searching for key 'unique-param' in [environmentProperties]
...

Т.е. поиск (резолвинг) был проведен дважды. Конечно, это слишком мизерная операция, чтобы хоть как-то замедлить старт приложения, но знать об этом стоит.


Еще более неоднозначная штука связана с передачей дефолтного значения через @Value.

@Value("${unique-param:DefaultValue}")
private String param;

При резолвинге значения будет сначала проведен поиск параметра “unique-param:DefaultValue”, а уже потом - “unique-param”. Таким образом, если в конфигурации указать:

unique-param\:DefaultValue = Another value

, то param в коде будет равен “Another value”.

Такая логика прописана в org.springframework.util.PropertyPlaceholderHelper#parseStringValue.


Оба этих нюанса могут ответить на вопрос - почему debug-лог приложения на Spring Boot такой большой.

Мораль - используйте ConfigurationProperties, что, в конце-концов, и советуется в 23. Externalized Configuration, раздел “23.7 Typesafe Configuration Properties”.

Например:

@ConfigurationProperties(prefix = "params")
public class Config {
    private String uniqueParam = "Default value";

    // Getters are mandatory. Setters are mandatory for immutable types (such as String).
 }

Конфигурация:

params.unique-param = Another value
Tags:
comments powered by Disqus