Свойства Spring @Configuration. Spring предоставляет несколько способов… | автор Хабиб Окунаде | Средний
Хабиб Окунаде ・ 1 марта 2020 года ・ 10 минут чтения в среднем
Spring предоставляет несколько способов ввода/поиска значений из файла свойств конфигурации приложения.
Одним из них является аннотация @Value , обсуждаемая в статье Трюки с аннотациями Spring @Value .
Другим является использование аннотации @ConfigurationProperties в компоненте конфигурации для ввода значений свойств в компонент и использования его в классе. Также используется Среда объект для поиска значений, свойств или профилей в пути к классу.
В этой статье я продемонстрирую, как использовать аннотацию @ConfigurationProperties для ввода значений свойств из application.properties или приложение.yaml файлы.
Отпустить, чтобы https://start.spring.io/ для создания и начальной загрузки вашего проекта. Выберите проект Maven, Java в качестве языка, укажите вашему проекту имя группы и идентификатор артефакта. Выберите Spring Web в качестве единственной зависимости для нашего проекта.
Нажмите кнопку “Создать”, чтобы загрузить загруженный проект в виде zip-файла. Распакуйте файл и откройте его с помощью предпочитаемой вами среды разработки в качестве проекта Maven, чтобы загрузить все необходимые зависимости, и в конце всего этого структура вашего проекта должна выглядеть так, как показано на рисунке ниже:
Откройте файл application.properties и запишите значения свойств ниже:
#DEV environment properties dev.name=Development Application dev.port=8091 dev.dbtype=Maria DB dev.version=1.0.alpha dev.dburl=jdbc:mariadb://localhost:3306/ dev.dbname=studentDB dev.dbuser=root dev.dbpassword=root #QA environment properties qa.name=QA Test Application qa.port=8092 qa.dbtype=Mongo DB qa.version=1.2.beta qa.dburl=mongodb://mongodb0.example.com:27017/ qa.dbname=studentDB qa.dbuser=admin qa.dbpassword=admin #PROD environment properties prod.name=Production Application prod.port=8091 prod.dbtype=MySQL prod.version=1.0.1 prod.dburl=jdbc:mysql://localhost:3308/ prod.dbname=studentDB prod.dbuser=admin-prod prod.dbpassword=admin-prod
Файл содержит три значения свойств для трех разных сред — dev, qa и prod. Каждому свойству присваивается префикс типа среды, к которой они принадлежат. Не рекомендуется размещать все эти специфические свойства среды в одном файле. На самом деле мы не можем иметь разные свойства среды, подобные этому, а скорее создаем определенный файл свойств приложения для каждой среды, настраиваем профиль и выбираем активный профиль или профили для использования. Просто потерпите меня с этим подходом, чтобы показать, как использовать аннотацию. Наша цель состоит в том, чтобы загрузить эти свойства в наше приложение, создав компоненты и используя аннотацию @ConfigurationProperties .
Давайте создадим пакет под названием config и создадим три класса DevConfigProps.java , QaConfigProps.java и ProdConfigProps.java в этом пакете и аннотируйте каждый класс с помощью @Configuration , чтобы сообщить spring, что эти классы должны сканироваться, управляться и настраиваться как компоненты spring во время загрузки приложения.
Если вы рассмотрите файл application.properties выше, вы заметите, что каждое из этих свойств имеет префикс dev , контроль качества или подталкивать . Эти префиксы будут использоваться для настройки этих классов с помощью аннотации @ConfigurationProperties(“префикс”) .
@Свойства конфигурации(“разработчик”) для свойств разработчика, @ConfigurationProperties(“контроль качества”) для свойств контроля качества и @Свойства конфигурации(“prod”) для свойств продукта.
//DevConfigProps.java
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("dev")
public class DevConfigProps {
}
//QaConfigProps.java
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("qa")
public class QaConfigProps {
}
//ProdConfigProps.java
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("prod")
public class ProdConfigProps {
}
@ConfigurationProperties позволяет нам легко сопоставлять все свойства или файлы YAML в объект. Это также позволяет нам проверять свойства с помощью проверки компонентов JSR-303. По умолчанию аннотация считывается из файла application.properties . Используемый файл свойств можно изменить с помощью аннотации @PropertySource(“имя файла”) , если мы не хотим использовать файл свойств по умолчанию.
Следующим шагом будет создание всех имен свойств в виде переменной с их установщиками и получателями.
для для
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("dev")
public class DevConfigProps {
private String name;
private int port;
private String dbType;
private String version;
private String dbUrl;
private String dbName;
private String dbUser;
private String dbPassword;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDbUrl() {
return dbUrl;
}
public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getDbUser() {
return dbUser;
}
public void setDbUser(String dbUser) {
this.dbUser = dbUser;
}
public String getDbPassword() {
return dbPassword;
}
public void setDbPassword(String dbPassword) {
this.dbPassword = dbPassword;
}
}
для QaConfigProps.java
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("qa")
public class QaConfigProps {
private String name;
private int port;
private String dbType;
private String version;
private String dbUrl;
private String dbName;
private String dbUser;
private String dbPassword;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDbUrl() {
return dbUrl;
}
public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getDbUser() {
return dbUser;
}
public void setDbUser(String dbUser) {
this.dbUser = dbUser;
}
public String getDbPassword() {
return dbPassword;
}
public void setDbPassword(String dbPassword) {
this.dbPassword = dbPassword;
}
}
для ProdConfigProps.java
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("prod")
public class ProdConfigProps {
private String name;
private int port;
private String dbType;
private String version;
private String dbUrl;
private String dbName;
private String dbUser;
private String dbPassword;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDbUrl() {
return dbUrl;
}
public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getDbUser() {
return dbUser;
}
public void setDbUser(String dbUser) {
this.dbUser = dbUser;
}
public String getDbPassword() {
return dbPassword;
}
public void setDbPassword(String dbPassword) {
this.dbPassword = dbPassword;
}
}
Чтобы проверить наши свойства, давайте создадим класс конфигурации, который реализует CommandLineRunner чтобы мы могли регистрировать все свойства, настроенные в его методе run . В этом классе мы будем автоматически подключать эти три класса конфигурации, поскольку они являются компонентами, управляемыми spring.
package com.habeebcycle.configurationpropertiesannotation;
import com.habeebcycle.configurationpropertiesannotation.config.DevConfigProps;
import com.habeebcycle.configurationpropertiesannotation.config.ProdConfigProps;
import com.habeebcycle.configurationpropertiesannotation.config.QaConfigProps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
@Configuration
public class PropertiesConfig implements CommandLineRunner {
private final DevConfigProps devConfigProps;
private final QaConfigProps qaConfigProps;
private final ProdConfigProps prodConfigProps;
private static final Logger logger = LoggerFactory.getLogger(
ConfigurationPropertiesAnnotationApplication.class);
@Autowired
public PropertiesConfig(DevConfigProps devConfigProps,
QaConfigProps qaConfigProps, ProdConfigProps prodConfigProps) {
this.devConfigProps = devConfigProps;
this.qaConfigProps = qaConfigProps;
this.prodConfigProps = prodConfigProps;
}
@Override
public void run(String... args) throws Exception {
logger.info("-------------Dev Properties-----------------");
logger.info("Name: {}", devConfigProps.getName());
logger.info("Port: {}", devConfigProps.getPort());
logger.info("DB Type: {}", devConfigProps.getDbType());
logger.info("Version: {}", devConfigProps.getVersion());
logger.info("DB Url: {}", devConfigProps.getDbUrl());
logger.info("DB name: {}", devConfigProps.getDbName());
logger.info("DB User: {}", devConfigProps.getDbUser());
logger.info("DB Password: {}", devConfigProps.getDbPassword());
logger.info("-------------QA Properties-----------------");
logger.info("Name: {}", qaConfigProps.getName());
logger.info("Port: {}", qaConfigProps.getPort());
logger.info("DB Type: {}", qaConfigProps.getDbType());
logger.info("Version: {}", qaConfigProps.getVersion());
logger.info("DB Url: {}", qaConfigProps.getDbUrl());
logger.info("DB name: {}", qaConfigProps.getDbName());
logger.info("DB User: {}", qaConfigProps.getDbUser());
logger.info("DB Password: {}", qaConfigProps.getDbPassword());
logger.info("-------------Prod Properties---------------");
logger.info("Name: {}", prodConfigProps.getName());
logger.info("Port: {}", prodConfigProps.getPort());
logger.info("DB Type: {}", prodConfigProps.getDbType());
logger.info("Version: {}", prodConfigProps.getVersion());
logger.info("DB Url: {}", prodConfigProps.getDbUrl());
logger.info("DB name: {}", prodConfigProps.getDbName());
logger.info("DB User: {}", prodConfigProps.getDbUser());
logger.info("DB Password: {}", prodConfigProps.getDbPassword());
}
}
Запуск приложения в качестве приложения Spring Boot приведет к регистрации следующего в консоли:
---------------------Dev Properties------------------------- 2020-03-01 17:26:25.625 [main]: Name: Development Application 2020-03-01 17:26:25.626 [main]: Port: 8091 2020-03-01 17:26:25.626 [main]: DB Type: Maria DB 2020-03-01 17:26:25.626 [main]: Version: 1.0.alpha 2020-03-01 17:26:25.626 [main]: DB Url: jdbc:mariadb://localhost:3306/ 2020-03-01 17:26:25.626 [main]: DB name: studentDB 2020-03-01 17:26:25.626 [main]: DB User: root 2020-03-01 17:26:25.627 [main]: DB Password: root ---------------------QA Properties------------------------- 2020-03-01 17:26:25.627 [main]: Name: QA Test Application 2020-03-01 17:26:25.627 [main]: Port: 8092 2020-03-01 17:26:25.627 [main]: DB Type: Mongo DB 2020-03-01 17:26:25.627 [main]: Version: 1.2.beta 2020-03-01 17:26:25.627 [main]: DB Url: mongodb://mongodb0.example.com:27017/ 2020-03-01 17:26:25.627 [main]: DB name: studentDB 2020-03-01 17:26:25.627 [main]: DB User: admin 2020-03-01 17:26:25.627 [main]: DB Password: admin ---------------------Prod Properties------------------------- 2020-03-01 17:26:25.627 [main]: Name: Production Application 2020-03-01 17:26:25.627 [main]: Port: 8091 2020-03-01 17:26:25.627 [main]: DB Type: MySQL 2020-03-01 17:26:25.628 [main]: Version: 1.0.1 2020-03-01 17:26:25.628 [main]: DB Url: jdbc:mysql://localhost:3308/ 2020-03-01 17:26:25.628 [main]: DB name: studentDB 2020-03-01 17:26:25.628 [main]: DB User: admin-prod 2020-03-01 17:26:25.628 [main]: DB Password: admin-prod
Использование @ConfigurationProperties для ввода свойств списка.
Мы также можем использовать @ConfigurationProperties для чтения значений списка из файла свойств.
#application.properties dev.mylist=SUN,MON,TUE,WED,THU,FRI,SAT
и используйте @ConfigurationProperties для ввода списка следующим образом
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
@ConfigurationProperties("dev")
public class DevConfigProps {
private List myList;
public List getMyList() {
return myList;
}
public void setMyList(List myList) {
this.myList = myList;
}
}
Регистрация собственности дает
[SUN, MON, TUE, WED, THU, FRI, SAT]
Использование @ConfigurationProperties для ввода свойств карты (пар ключ-значение)
свойства пары ключ-значение могут быть прочитаны или введены с помощью аннотации @ConfigurationProperties следующим образом:
#application.properties dev.db.url=jdbc:mysql://localhost:3308/ dev.db.name=student_marks dev.db.user=root dev.db.password=root
Из приведенного выше файла свойств мы видим, что после префикса разработка , у нас есть бд . Это db будет переменной, используемой для ввода значений в виде сопоставления ключ-значение.
package com.habeebcycle.configurationpropertiesannotation.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
@Configuration
@ConfigurationProperties("dev")
public class DevConfigProps {
private Map db;
public Map getDb() {
return db;
}
public void setDb(Map db) {
this.db = db;
}
}
Spring автоматически введет вложенные свойства в переменные db в качестве переменной карты.
При выходе из системы значение свойства dev Config Props.get Db() выведет следующее:
{
"url": "jdbc:mysql://localhost:3308/",
"name": "student_marks",
"user": "root",
"password": "root"
}
Использование @ConfigurationProperties для внедрения класса (объекта) из файл свойств
Давайте создадим класс под названием Student.java
package com.habeebcycle.configurationpropertiesannotation.model;
public class Student {
private String id;
private String name;
private int age;
private String level;
private double mark;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public double getMark() {
return mark;
}
public void setMark(double mark) {
this.mark = mark;
}
}
Если у нас есть файл свойств следующим образом
#application.properties dev.student.id=ABC123XYZ dev.student.name=Habeeb Okunade dev.student.age=34 dev.student.level=700J dev.student.mark=99.4
Из приведенного выше файла свойств мы видим, что после префикса дев, у нас есть студент* . Этот студент будет переменной, используемой для ввода значений в качестве Студент * объект.
package com.habeebcycle.configurationpropertiesannotation.config;
import com.habeebcycle.configurationpropertiesannotation.model.Student;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("dev")
public class DevConfigProps {
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
Spring автоматически введет вложенные свойства в объект student в качестве переменной Student.
При выходе из значения свойства dev Config Props.get Student() будет выведено следующее:
{
"id": "ABC123XYZ",
"name": "Habeeb Okunade",
"age": 34,
"level": "700J",
"mark": 99.4
}
Использование свойств @ConfigurationProperties в методе @Bean
Мы также можем использовать @ConfigurationProperties аннотации к @компонентам – аннотированным методам.
Этот подход может быть особенно полезен, когда мы хотим привязать свойства к стороннему компоненту, который находится вне нашего контроля.
Давайте создадим простой Школьный класс, чтобы показать, как это использовать:
package com.habeebcycle.configurationpropertiesannotation.model;
public class School{
private String id;
private String name;
private int size;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
Теперь давайте посмотрим, как мы можем использовать @ConfigurationProperties в методе @Bean для привязки внешних свойств к экземпляру School :
package com.habeebcycle.configurationpropertiesannotation.config;
@Configuration
public class ExternalConfigProperties {
@Bean
@ConfigurationProperties("school")
public School school() {
return new School();
}
}
Таким образом, любое свойство school с префиксом будет сопоставлено с * *Школа экземпляр, управляемый контекстом Spring.
Использование @ConfigurationProperties для проверки свойств
@ConfigurationProperties обеспечивает проверку свойств с использованием формата JSR-303. Это позволяет нашим свойствам выглядеть аккуратно. Рассмотрим следующий класс:
package com.habeebcycle.configurationpropertiesannotation.config;
import org.hibernate.validator.constraints.Length;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
@Configuration
@ConfigurationProperties("validate")
@Validated
public class ConfigValidation {
@NotNull
private String dbUrl;
@Length(min = 4, max = 10)
private String dbUser;
@Min(8080)
@Max(8100)
private int dbPort;
@Pattern(regexp = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6}$")
private String adminEmail;
public String getDbUrl() {
return dbUrl;
}
public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}
public String getDbUser() {
return dbUser;
}
public void setDbUser(String dbUser) {
this.dbUser = dbUser;
}
public int getDbPort() {
return dbPort;
}
public void setDbPort(int dbPort) {
this.dbPort = dbPort;
}
public String getAdminEmail() {
return adminEmail;
}
public void setAdminEmail(String adminEmail) {
this.adminEmail = adminEmail;
}
}
В этом классе есть некоторые правила проверки для работы аннотации @ConfigurationProperties .
Аннотация @NotNull сообщает пружине, что поле dbUrl является обязательным и выдает ошибку, если оно не найдено.
Аннотация @Length(min=4,) проверяет dbUser только на ввод свойства длиной не менее 4 символов и 6 символов.
Значение @Мин и @Max аннотацию для ввода порта значения в диапазоне от 8080 до 8100.
наконец, свойство Adminemail должно соответствовать шаблону, указанному как @Шаблон(регулярное выражение)
Это помогает нам уменьшить количество условий if-else в нашем коде и делает его намного более чистым и лаконичным.
Если какая-либо из этих проверок завершится неудачей, то основное приложение не сможет запуститься с IllegalStateException .
В этой статье я показал, как использовать @ConfigurationProperties для чтения/ввода свойств конфигурации из файла свойств, и объяснил некоторые удобные функции, которые он предоставляет, такие как сопоставление свойств, привязка и проверка.
Оригинал: “https://dev.to/habeebcycle/spring-configurationproperties-annotation-explained-1lfp”