[번역] Spring Boot의 @ConfigurationProperties 가이드

in configuration •  3 years ago 

https://www.baeldung.com/configuration-properties-in-spring-boot/ 를 번역함.

1. 소개

Spring Boot에는 외부화된 구성과 속성 파일에 정의된 속성에 대한 쉬운 액세스를 포함하여 많은 유용한 기능이 있습니다 . 이전 자습서 에서는 이를 수행할 수 있는 다양한 방법을 설명했습니다.

이제 @ConfigurationProperties 주석을 더 자세히 살펴보겠습니다.

2. 설정

이 튜토리얼은 상당히 표준적인 설정을 사용합니다. pom.xml에 spring-boot-starter-parent 를 부모 로 추가하는 것으로 시작합니다 .

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/>
</parent>

파일에 정의된 속성을 검증할 수 있으려면 JSR-303의 구현도 필요하며 hibernate-validator 가 그 중 하나입니다.

pom.xml 에도 추가해 보겠습니다 .

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
</dependency>

"최대 절전 모드 검사기 시작" 페이지에 자세한 내용이 있습니다.

3. 단순 속성

공식 문서에서는 구성 속성을 별도의 POJO로 분리할 것을 권장 합니다.

다음을 수행하여 시작하겠습니다.

@Configuration
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {

private String hostName;
private int port;
private String from;

// standard getters and setters
}

Spring이 애플리케이션 컨텍스트에서 Spring 빈을 생성 하도록 @Configuration 사용 합니다.

@ConfigurationProperties 는 모두 동일한 접두사를 갖는 계층적 속성에서 가장 잘 작동합니다. 따라서 mail 접두사를 추가합니다.

Spring 프레임워크는 표준 Java bean setter를 사용하므로 각 속성에 대한 setter를 선언해야 합니다.

참고: POJO에서 @Configuration 을 사용하지 않으면 기본 Spring 애플리케이션 클래스에 @EnableConfigurationProperties(ConfigProperties.class) 를 추가 하여 속성을 POJO에 바인딩해야 합니다.

@SpringBootApplication
@EnableConfigurationProperties(ConfigProperties.class)
public class EnableConfigurationDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EnableConfigurationDemoApplication.class, args);
}
}

그게 다야! Spring은 ConfigProperties 클래스 의 필드 중 하나와 이름이 같고 mail 접두사가 있는 속성 파일에 정의된 모든 속성을 자동으로 바인딩합니다 .

Spring은 속성을 바인딩하기 위해 몇 가지 완화된 규칙을 사용합니다. 결과적으로 다음 변형은 모두 hostName 속성에 바인딩됩니다 .

mail.hostName
mail.hostname
mail.host_name
mail.host-name
mail.HOST_NAME

따라서 다음 속성 파일을 사용하여 모든 필드를 설정할 수 있습니다.

#Simple properties
[email protected]
mail.port=9000
[email protected]

3.1. 스프링 부트 2.2

현재 봄 부팅 2.2 , 봄이 찾아 레지스터 @ConfigurationProperties 클래스 경로 검사를 통해 클래스를 . 따라서 @Component (및 @Configuration과 같은 기타 메타 주석)로 이러한 클래스에 주석을 달거나 @EnableConfigurationProperties를 사용할 필요가 없습니다.

@ConfigurationProperties(prefix = "mail") 
public class ConfigProperties {

private String hostName;
private int port;
private String from;

// standard getters and setters
}

@SpringBootApplication에 의해 활성화된 클래스 경로 스캐너 는 @Component 이 클래스에 주석을 달지 않았음에도 불구 하고 ConfigProperties 클래스를 찾습니다 .

또한 @ConfigurationPropertiesScan 주석을 사용 하여 구성 속성 클래스의 사용자 지정 위치를 스캔 할 수 있습니다 .

@SpringBootApplication
@ConfigurationPropertiesScan("com.baeldung.configurationproperties")
public class EnableConfigurationDemoApplication {

public static void main(String[] args) {
SpringApplication.run(EnableConfigurationDemoApplication.class, args);
}
}

이런 식으로 Spring은 com.baeldung.properties 패키지 에서만 구성 속성 클래스를 찾습니다 .

4. 중첩 속성

목록, 맵 및 클래스 에 중첩된 속성을 가질 수 있습니다 .

일부 중첩 속성에 사용할 새 Credentials 클래스를 만들어 보겠습니다 .

public class Credentials {
private String authMethod;
private String username;
private String password;

// standard getters and setters
}

우리는 또한 업데이트해야 ConfigProperties의 사용하는 클래스 목록, 지도 및 자격 증명 클래스를 :

public class ConfigProperties {

private String host;
private int port;
private String from;
private List<String> defaultRecipients;
private Map<String, String> additionalHeaders;
private Credentials credentials;

// standard getters and setters
}

다음 속성 파일은 모든 필드를 설정합니다.

#Simple properties
[email protected]
mail.port=9000
[email protected]

#List properties
mail.defaultRecipients[0][email protected]
mail.defaultRecipients[1][email protected]

#Map Properties
mail.additionalHeaders.redelivery=true
mail.additionalHeaders.secure=true

#Object properties
mail.credentials.username=john
mail.credentials.password=password
mail.credentials.authMethod=SHA1

5. @Bean 메소드 에서 @ConfigurationProperties 사용하기

@Bean 주석이 달린 메소드 에서 @ConfigurationProperties 주석을 사용할 수도 있습니다 .

이 접근 방식은 우리가 제어할 수 없는 타사 구성 요소에 속성을 바인딩하려는 경우에 특히 유용할 수 있습니다.

다음 예제에서 사용할 간단한 Item 클래스를 만들어 보겠습니다 .

public class Item {
private String name;
private int size;

// standard getters and setters
}

이제 @Bean 메서드에서 @ConfigurationProperties 를 사용 하여 외부화된 속성을 Item 인스턴스 에 바인딩 하는 방법을 살펴보겠습니다 .

@Configuration
public class ConfigProperties {

@Bean
@ConfigurationProperties(prefix = "item")
public Item item() {
return new Item();
}
}

결과적으로 항목 접두사가 붙은 속성은 Spring 컨텍스트에서 관리 하는 항목 인스턴스에 매핑됩니다 .

6. 속성 검증

@ConfigurationProperties 는 JSR-303 형식을 사용하여 속성의 유효성 검사를 제공합니다. 이것은 모든 종류의 깔끔한 것을 허용합니다.

예를 들어 hostName 속성을 필수로 지정해 보겠습니다 .

@NotBlank
private String hostName;

다음으로 authMethod 속성을 1~4자 길이로 만들어 보겠습니다 .

@Length(max = 4, min = 1)
private String authMethod;

그런 다음 1025에서 65536까지 의 포트 속성:

@Min(1025)
@Max(65536)
private int port;

마지막으로 from 속성은 이메일 주소 형식과 일치해야 합니다.

@Pattern(regexp = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6}$")
private String from;

이는 코드에서 if – else 조건을 많이 줄이는 데 도움이 되며 훨씬 깨끗하고 간결해 보입니다.

이러한 유효성 검사 중 하나라도 실패하면 기본 응용 프로그램이 IllegalStateException 으로 시작하는 데 실패 합니다 .

Hibernate Validation 프레임워크는 표준 Java Bean getter 및 setter를 사용하므로 각 속성에 대해 getter 및 setter를 선언하는 것이 중요합니다.

7. 재산 전환

@ConfigurationProperties 는 속성을 해당 빈에 바인딩하는 여러 유형의 변환을 지원합니다.

7.1. 지속

속성을 Duration 객체 로 변환하는 것부터 살펴보겠습니다 .

여기에 Duration 유형의 두 필드가 있습니다 .

@ConfigurationProperties(prefix = "conversion")
public class PropertyConversion {

private Duration timeInDefaultUnit;
private Duration timeInNano;
...
}

이것은 우리의 속성 파일입니다:

conversion.timeInDefaultUnit=10
conversion.timeInNano=9ns

결과적으로 timeInDefaultUnit 필드 의 값은 10밀리초이고 timeInNano 의 값은 9나노초입니다.

지원되는 단위는 각각 나노초, 마이크로초, 밀리초, 초, 분, 시간 및 일의 경우 ns, us, ms, s, m, h 및 d 입니다.

기본 단위는 밀리초입니다. 즉, 숫자 값 옆에 단위를 지정하지 않으면 Spring이 값을 밀리초로 변환합니다.

@DurationUnit 사용하여 기본 단위를 재정의할 수도 있습니다 .

@DurationUnit(ChronoUnit.DAYS)
private Duration timeInDays;

해당 속성은 다음과 같습니다.

conversion.timeInDays=2

7.2. 데이터 크기

마찬가지로 Spring Boot @ConfigurationProperties 는 DataSize 유형 변환을 지원합니다 .

DataSize 유형의 세 필드를 추가해 보겠습니다 .

private DataSize sizeInDefaultUnit;

private DataSize sizeInGB;

@DataSizeUnit(DataUnit.TERABYTES)
private DataSize sizeInTB;

해당 속성은 다음과 같습니다.

conversion.sizeInDefaultUnit=300
conversion.sizeInGB=2GB
conversion.sizeInTB=4

이 경우 기본 단위가 바이트 이므로 sizeInDefaultUnit 값은 300바이트가 됩니다.

지원되는 단위는 B, KB, MB, GB 및 TB입니다. @DataSizeUnit 사용하여 기본 단위를 재정의할 수도 있습니다 .

7.3. 사용자 정의 변환기

속성을 특정 클래스 유형으로 변환하는 것을 지원하기 위해 자체 사용자 정의 변환기 를 추가할 수도 있습니다 .

간단한 Employee 클래스를 추가해 보겠습니다 .

public class Employee {
private String name;
private double salary;
}

그런 다음 이 속성을 변환하는 사용자 지정 변환기를 만듭니다.

conversion.employee=john,2000

Employee 유형의 파일로 변환합니다 .

private Employee employee;

Converter 인터페이스 를 구현 한 다음 @ConfigurationPropertiesBinding 주석을 사용 하여 사용자 지정 Converter 를 등록해야 합니다 .

@Component
@ConfigurationPropertiesBinding
public class EmployeeConverter implements Converter<String, Employee> {

@Override
public Employee convert(String from) {
String[] data = from.split(",");
return new Employee(data[0], Double.parseDouble(data[1]));
}
}

8. 불변 @ConfigurationProperties 바인딩

Spring Boot 2.2부터 @ConstructorBinding 주석을 사용하여 구성 속성을 바인딩할 수 있습니다 .

이것은 본질적으로 @ConfigurationProperties 주석이 달린 클래스가 이제 변경 불가능할 수 있음을 의미합니다 .

@ConfigurationProperties(prefix = "mail.credentials")
@ConstructorBinding
public class ImmutableCredentials {

private final String authMethod;
private final String username;
private final String password;

public ImmutableCredentials(String authMethod, String username, String password) {
this.authMethod = authMethod;
this.username = username;
this.password = password;
}

public String getAuthMethod() {
return authMethod;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}
}

보시다시피 @ConstructorBinding을 사용할 때  바인딩하려는 모든 매개변수를 생성자에 제공해야 합니다.

ImmutableCredentials의 모든 필드   는 최종적입니다. 또한 setter 메서드가 없습니다.

또한 생성자 바인딩을 사용하려면 @EnableConfigurationProperties  또는  @ConfigurationPropertiesScan 을 사용하여 구성 클래스를 명시적으로 활성화해야  한다는 점을 강조하는 것이 중요합니다 .

9. 자바 (16)  기록 들

Java 16 은 JEP 395의 일부로 레코드  유형을 도입했습니다  . 레코드는 변경할 수 없는 데이터의 투명한 전달자 역할을 하는 클래스입니다. 따라서 구성 보유자 및 DTO에 대한 완벽한 후보입니다. 사실 Spring Boot에서 Java 레코드를 구성 속성으로 정의할 수 있습니다 . 예를 들어 이전 예제는 다음과 같이 다시 작성할 수 있습니다.

@ConstructorBinding
@ConfigurationProperties(prefix = "mail.credentials")
public record ImmutableCredentials(String authMethod, String username, String password) {
}

분명히 모든 시끄러운 getter 및 setter에 비해 더 간결합니다.

또한 Spring Boot 2.6 부터 단일 생성자 레코드의 경우 @ConstructorBinding  주석을 삭제할 수 있습니다  . 그러나 레코드에 여러 생성자가 있는 경우 @ConstructorBinding 을 사용하여 속성 바인딩에 사용할 생성자를 식별해야 합니다.

10. 결론

이 기사에서는 @ConfigurationProperties 주석 을 살펴보고 완화된 바인딩 및 Bean 유효성 검사와 같이 주석이 제공하는 몇 가지 유용한 기능을 강조했습니다.

평소와 같이 코드는 Github에서 사용할 수 있습니다 .



Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!