👨💻
Spring Tips: работаем со свойствамиБолее миллиона раз разработчики обращались к
вопросу на StackOverflow о том, как получить значение из
application.properties. Возможно, вы удивитесь
(хотя я очень сильно сомневаюсь в этом), но отмеченный как верный ответ с
@Value – это не единственный способ. И далеко не всегда самый удобный.
Способ №1: @ValueАннотация
@Value используется для инъекции отдельных значений из файла конфигурации. Например:
@Value("${property.name}")
private String propertyName;
Пожалуй, самый простой, но не самый поддерживаемый вариант, из-за отсутствия группировки и большого количества дублирующего кода, когда значений, с которыми надо работать, становится довольного много.
Способ №2: @ConfigurationPropertiesАннотация
@ConfigurationProperties используется для группировки связанных свойств в объект класса. Свойства могут настраиваться через
.properties и
.yaml файлы, переменные окружения и т.д.
Типичное использование
@ConfigurationProperties может выглядеть следующим образом:
@ConfigurationProperties(prefix = "app")
@Component
@Getter
@Setter
public class ApplicationProperties {
private String name;
}
@SpringBootTest(properties = "app.name=my-app")
class ApplicationPropertiesTest {
@Autowired
private ApplicationProperties applicationProperties;
@Test
void appName() {
var appName = applicationProperties.getName();
assertEquals("my-app", appName);
}
}
Да, нужно будет создать отдельный класс, зато преимуществ у этого подхода относительно
@Value довольно много. Перечислим некоторые из них:
– Группировка по префиксу
– Возможность
иерархического представления свойств– Это бин и этим всё сказано :)
–
@ConfigurationPropertiesBinding– Кто сможет назвать ещё парочку преимуществ в комментариях?)Отдельно отметим
@ConfigurationPropertiesBinding. Допустим, нам нужно добавить новое свойство
version, которое будет представлять класс
Version для обработки семантического версионирования (major.minor.patch).
@ConfigurationProperties(prefix = "app")
@Component
@Getter
@Setter
public class ApplicationProperties {
private String name;
private Version version;
}
Для преобразования строкового значения из конфигурации в объект класса
Version нам потребуется конвертор, который как раз будет отмечен аннотацией
@ConfigurationPropertiesBinding:
@ConfigurationPropertiesBinding
@Component
class SemVerPropertyConverter implements Converter<String, Version> {
@Override
public Version convert(String source) {
return StringUtils.hasLength(source) ? Version.parse(source) : null;
}
}
Пример использования:
@SpringBootTest(properties = {
"app.name=my-app",
"app.version=1.1.0"
})
class ApplicationPropertiesTest {
@Autowired
private ApplicationProperties applicationProperties;
@Test
void appVersion() {
Version version = applicationProperties.getVersion();
assertEquals(1, version.getMajorVersion());
assertEquals(1, version.getMinorVersion());
assertEquals(0, version.getPatchVersion());
}
}
Подробнее про
@ConfigurationProperties и
@ConfigurationPropertiesBinding вы можете прочитать в
документации.
Способ №3: EnvironmentА если вы хотите обойтись без специальных аннотаций, можно использовать
Environment:
@Autowired
private Environment env;
public void someMethod() {
String property = env.getProperty("property.name");
}
#SpringBoot #SpringTips