Web
@ConfigurationProperties
8/14/2024
스프링에서는 @ConfigurationProperties 애노테이션을 통해 외부 설정을 객체로 만들어 시스템 내에서 사용할 수 있게 해준다. 이를 통해 단순히 외부 설정을 매핑하는 것 뿐만 아니라 객체의 이점을 살리는 방식으로 프로그래밍을 할 수 있게 도와준다.
@ConfigurationProperties
사용하고자 하는 속성들이 존재하는 클래스를 생성한 뒤, 애노테이션 엘리먼트에 해당 속성들의 기본 주소를 작성한다. 이후 이 클래스를 등록하면, 스프링은 기본 주소와 변수명을 토대로 외부 설정값을 읽어와 값을 저장한다.
기본 주입 방식은 Java Bean Property 방식인 getter, setter를 사용하므로 이에 해당하는 코드는 작성해주어야 한다.
@Data
@ConfigurationProperties("db.mysql")
public class MySQLProperties {
private String host;
private Integer port;
private String db;
}
위와 같이 작성한 경우 application.properties 등으로 제공한 db.mysql.host, db.mysql.port, db.mysql.db 의 정보를 읽어서 각 필드에 매핑한다. 사실 위 코드만으로 동작하지는 않고, 해당 클래스가 구성정보를 읽어올 수 있도록 추가적인 정보를 스프링 측에 알려야 한다.
@Configuration
@EnableConfigurationProperties(MySQLProperties.class)
public class ConfigurationPropertiesConfig {}
위 코드까지 작성된 이후라면, 스프링은 컨테이너 초기화 시점에서 MySQLProperties의 빈을 등록한다. 이 과정에서 타입 검증을 수행해, 맞지 않는 경우 오류를 내뱉고 프로그램을 중지시킨다.
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'db.mysql.port' to java.lang.Integer:
Property: db.mysql.port
Value: "port"
Origin: class path resource [application.properties] - 5:15
Reason: failed to convert java.lang.String to java.lang.Integer (caused by java.lang.NumberFormatException: For input string: "port")
Action:
Update your application's configuration
심지어 Intellij는 Java 코드를 읽어 필요한 환경변수를 분석하고, 타입이 다른 경우 경고를 띄워주기도 한다.

@ConfigurationPropertiesScan
@EnableConfigurationProperties는 등록하고자 하는 환경변수를 하나하나 작성해줘야 한다는 번거로움이 있는데, 이 문제를 해결하기 위해서는 @ConfigurationPropertiesScan을 사용할 수 있다. 애노테이션 속성인 basePackage를 설정하지 않는다면 @ConfigurationPropertiesScan이 붙어있는 설정클래스와 같은 패키지거나 하위 패키지를 대상으로 @ConfigurationProperties가 붙은 클래스를 읽어 설정 정보 빈을 등록한다.
@Configuration
//@EnableConfigurationProperties(MySQLProperties.class)
@ConfigurationPropertiesScan
public class ConfigurationPropertiesConfig {
}
생성자 방식 등록
하지만 getter setter가 존재하는 객체는 객체의 생명주기 내에서 값이 변화될 가능성을 낳는다. 이러한 문제를 방지하기 위해서 설정 정보를 생성자를 통해 주입시킬 수 있다. 스프링은 생성자가 하나라면 해당 생성자를 통해 설정 정보를 주입해준다.
@Getter
@ConfigurationProperties(prefix = "db.mysql")
public class MySQLProperties {
private final String host;
private final Integer port;
private final String db;
public MySQLProperties(String host, Integer port, String db) {
this.host = host;
this.port = port;
this.db = db;
}
}
구성정보 검증
위 기술만으로 간단한 타입 검증은 되지만 값 자체를 정밀하게 검증할 수는 없다. 스프링은 Java Bean Validator를 통해 구성정보를 검증할 수 있게 도와준다.
@ConfigurationProperties(prefix = "db.mysql")
@Validated
public class MySQLProperties {
private final String host;
private final Integer port;
private final String db;
@Min(1)
@Max(100)
private final Integer poolSize;
public MySQLProperties(String host, Integer port, String db, Integer poolSize) {
this.host = host;
this.port = port;
this.db = db;
this.poolSize = poolSize;
}
}
위와 같이 클래스 레벨에 @Validated 애노테이션과 필드에 Validator 애노테이션을 부착해놓으면 초기화 시점에 검증을 수행하고, 실패한 경우 에러 문구와 함께 프로그램을 종료시킨다.
***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target com.example.demo.MySQLProperties failed:
Property: db.mysql.poolSize
Value: "1000"
Origin: class path resource [application.properties] - 6:20
Reason: 100 이하여야 합니다
Action:
Update your application's configuration