Рубрики
Без рубрики

Пояснена аннотация Spring @ConfigurationProperties

Весна @Свойства конфигурации – Хабиб Окунаде – Средний… Помеченный spring, микросервисами, java, аннотациями.

Свойства 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”