728x90
@ConfigurationProperties를 통해서 숫자가 들어가야 하는 부분에 문자가 입력되는 문제와 같은 타입이 맞지 않는 데이터를 입력하는 문제는 예방할 수 있다. 그런데 문제는 숫자의 범위라던가, 문자의 길이 같은 부분은 검증이 어렵다.
예를 들어서 최대 커넥션 숫자는 최소 1, 최대 999라는 범위를 가져야 한다면 어떻게 검증할 수 있을까? 이메일을 외부 설정에 입력했는데, 만약 이메일 형식에 맞지 않는다면 어떻게 검증할 수 있을까?
개발자가 직접 하나하나 검증 코드를 작성해도 되지만, 자바에는 자바 빈 검증기(java bean validation)이라는 훌륭한 표준 검증기가 제공된다.
@ConfigurationProperties 은 자바 객체이기 때문에 스프링이 자바 빈 검증기를 사용할 수 있도록 지원한다.
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-validation' //추가
//test lombok 사용
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}
MyDataSourcePropertiesV3
@Getter
@Validated
@ConfigurationProperties("my.datasource")
public class MyDataSourcePropertiesV3 {
@NotEmpty
private String url;
@NotEmpty
private String username;
@NotEmpty
private String password;
private Etc etc;
//@ConstructorBinding //생성자가 하나일 경우에는 생략 가능하다
public MyDataSourcePropertiesV3(String url, String username, String password,
@DefaultValue Etc etc) {
this.url = url;
this.username = username;
this.password = password;
this.etc = etc;
}
@Getter
public static class Etc {
@Min(1)
@Max(999)
private int maxConnection;
@DurationMin(seconds = 1)
@DurationMax(seconds = 60)
private Duration timeout;
private List<String> options;
public Etc(int maxConnection, Duration timeout, @DefaultValue("DEFAULT") List<String> options) {
this.maxConnection = maxConnection;
this.timeout = timeout;
this.options = options;
}
}
}
- @NotEmpty url , username , password 는 항상 값이 있어야 한다. 필수 값이 된다.
- @Min(1) @Max(999) maxConnection : 최소 1 , 최대 999 의 값을 허용한다.
- @DurationMin(seconds = 1) @DurationMax(seconds = 60) : 최소 1, 최대 60초를 허용한다
- jakarta.validation.constraints.Max
- 패키지 이름에 jakarta.validation 으로 시작하는 것은 자바 표준 검증기에서 지원하는 기능이다.
- org.hibernate.validator.constraints.time.DurationMax
- 패키지 이름에 org.hibernate.validator 로 시작하는 것은 자바 표준 검증기에서 아직 표준화 된 기능은 아니고, 하이버네이트 검증기라는 표준 검증기의 구현체에서 직접 제공하는 기능이다. 대부분 하이버네이트 검증기를 사용하므로 이 부분이 크게 문제가 되지는 않는다.
MyDataSourceConfigV3
@Slf4j
@EnableConfigurationProperties(MyDataSourcePropertiesV3.class)
public class MyDataSourceConfigV3 {
private final MyDataSourcePropertiesV3 properties;
public MyDataSourceConfigV3(MyDataSourcePropertiesV3 properties) {
this.properties = properties;
}
@Bean
public MyDataSource dataSource() {
return new MyDataSource(properties.getUrl(),
properties.getUsername(),
properties.getPassword(),
properties.getEtc().getMaxConnection(),
properties.getEtc().getTimeout(),
properties.getEtc().getOptions());
}
}
- MyDataSourceConfigV3 은 기존 코드와 크게 다르지 않다.
ExternalReadApplication - 수정
@Import(MyDataSourceConfigV3.class)
@SpringBootApplication(scanBasePackages = "hello.datasource")
@ConfigurationPropertiesScan({"hello"}) //해당 어노테이션이 있으면 ComponentScan 처럼 빈을 등록 안해도 된다.
public class ExternalReadApplication {
public static void main(String[] args) {
SpringApplication.run(ExternalReadApplication.class, args);
}
}
- @Import(MyDataSourceConfigV3.class) 를 추가 한다.
정리
ConfigurationProperties 덕분에 타입 안전하고, 또 매우 편리하게 외부 설정을 사용할 수 있다. 그리고 검증기 덕분에 쉽고 편리하게 설정 정보를 검증할 수 있다.
가장 좋은 예외는 컴파일 예외, 그리고 애플리케이션 로딩 시점에 발생하는 예외이다. 가장 나쁜 예외는 고객 서비스 중에 발생하는 런타임 예외이다.
ConfigurationProperties 장점
- 외부 설정을 객체로 편리하게 변환해서 사용할 수 있다.
- 외부 설정의 계층을 객체로 편리하게 표현할 수 있다.
- 외부 설정을 타입 안전하게 사용할 수 있다.
- 검증기를 적용할 수 있다.
728x90
'스프링 부트(핵심 원리와 활용)' 카테고리의 다른 글
| Ch06. 외부설정과 프로필(2) - @Profile (0) | 2023.03.18 |
|---|---|
| Ch06. 외부설정과 프로필(2) - YAML (0) | 2023.03.18 |
| Ch06. 외부설정과 프로필(2) - 외부 설정 사용(@ConfigurationProperties 생성자) (0) | 2023.03.18 |
| Ch06. 외부설정과 프로필(2) - 외부 설정 사용(@ConfigurationProperties 시작) (0) | 2023.03.18 |
| Ch06. 외부설정과 프로필(2) - 외부 설정 사용(@Value) (0) | 2023.03.15 |