@Value
@Value를 사용하면 외부 설정값을 편리하게 주입받을 수 있다. 물론 @Value도 내부에서 Environment를 사용한다.
@Slf4j
@Configuration
public class MyDataSourceValueConfig {
@Value("${my.datasource.url}")
private String url;
@Value("${my.datasource.username}")
private String username;
//...
@Bean
public MyDataSource myDataSource(
@Value("${my.datasource.url}") String url,
@Value("${my.datasource.username}") String username,
@Value("${my.datasource.password}") String password,
@Value("${my.datasource.etc.max-connection:1}") int maxConnection,
@Value("${my.datasource.etc.timeout}") Duration timeout,
@Value("${my.datasource.etc.options}") List<String> options) {
return new MyDataSource(url, username, password, maxConnection, timeout, options);
}
}
- @Value는 ${}를 사용해서 외부 설정의 키 값을 주면 원하는 값을 주입 받을 수 있다.
- @Value는 필드에 사용할 수도 있고, 파라미터에 사용할 수도 있다.
- 만약 키를 찾지 못할 경우 코드에서 기본값을 사용하면 된다. :뒤에 기본 값을 적으면 된다.
@ConfigurationProperties
스프링은 외부 설정의 묶음 정보를 객체로 변환하는 기능을 제공한다. 이것을 타입 안전한 설정 속성이라고 한다.
객체를 사용하면 타입을 사용해 잘못된 타입이 들어오는 실수를 방지할 수 있고 활용성도 높아진다.
@Getter
@ConfigurationProperties("my.datasource")
@Validated
public class MyDataSourcePropertiesV3 {
@NotEmpty
private String url;
@NotEmpty
private String username;
@NotEmpty
private String password;
private Etc etc;
public MyDataSourcePropertiesV3(String url, String username, String password, 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 = new ArrayList<>();
public Etc(int maxConnection, Duration timeout, List<String> options) {
this.maxConnection = maxConnection;
this.timeout = timeout;
this.options = options;
}
}
}
@ConfigurationProperties이 있으면 외부 설정을 주입받는 객체라는 뜻이다. 이를 사용하면 타입 안전한 설정 속성을 사용할 수 있다.
여기에 외부 설정 KEY의 묶음 시작점 실습에서는 my.datasource를 넣어준다. 이 묶음 시작점을 prefix라고 부른다.
즉 prefix와 일치하는 값들을 넣어주는 것이다.
기본 주입 방식은 자바 빈 프로퍼티 방식이다. 그러나 생성자를 사용하는 것이 안전하다.
또한 @ConfigurationProperties는 자바 객체이므로 스프링이 자바 빈 검증기를 사용할 수 있도록 지원한다.
@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());
}
}
@EnableConfigurationProperties는 스프링에게 사용할 @MyDataSourceProperties를 지정해주어야 한다.
이렇게 하면 해당 클래스는 스프링 빈으로 등록되고, 필요한 곳에서 주입 받아서 사용할 수 있다.
정리하면 application.properties에 필요한 외부 설정을 추가하고,
@ConfigurationProperties를 통해서 MyDataSourceProperties에 외부 설정의 값들을 설정했다.
그리고 해당 값들을 읽어서 MyDataSource를 만들었다.
참고로 스프링은 캐밥 표기법을 자바 낙타 표기법으로 중간에서 자동으로 변환해준다.
@ConfigurationPropertiesScan
위 애노테이션은 컴포넌트 스캔과 비슷하게 동작한다.
@ConfigurationProperties를 특정 범위로 자동 등록할 때 위 애노테이션을 사용한다.
@ConfigurationProperties 장점
- 외부 설정을 객체로 편리하게 변환해서 사용할 수 있다.
- 외부 설정의 계층을 객체로 편리하게 표현할 수 있다.
- 외부 설정을 타입 안전하게 사용할 수 있다.
- 검증기를 적용할 수 있다.
YAML
스프링은 설정 데이터를 사용할 때 application.properties뿐만 아니라 application.yml도 지원한다.
---로 논리 파일을 구분하며 spring.config.active.on-profile을 사용해 프로필을 적용할 수 있다.
my:
datasource:
url: local.db.com
username: local_user
password: local_pw
etc:
max-connection: 1
timeout: 60s
options: LOCAL, CACHE
--- # 구분
spring:
config:
activate:
on-profile: dev
my:
datasource:
url: dev.db.com
username: dev_user
password: dev_pw
etc:
maxConnection: 10
timeout: 60s
options: DEV, CACHE
--- # 구분
spring:
config:
activate:
on-profile: prod
my:
datasource:
url: prod.db.com
username: prod_user
password: prod_pw
etc:
maxConnection: 50
timeout: 10s
options: PROD, CACHE
@Profile
@Profile 애노테이션을 사용하면 해당 프로필이 활성화된 경우에만 스프링 빈을 등록한다.
@Profile("default")
//프로필이 활성화 되어 있으면 빈으로 등록한다.
//...
@Profile("prod")
//prod 프로필이 활성화 되어 있으면 빈으로 등록.
//...
참고자료
댓글