개발/Spring Boot

@Value, @ConfigurationProperties, @Profile

Debin 2023. 3. 2.
반응형

@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 프로필이 활성화 되어 있으면 빈으로 등록.
//...

참고자료

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%ED%95%B5%EC%8B%AC%EC%9B%90%EB%A6%AC-%ED%99%9C%EC%9A%A9/dashboard

 

스프링 부트 - 핵심 원리와 활용 - 인프런 | 강의

실무에 필요한 스프링 부트는 이 강의 하나로 모두 정리해드립니다., - 강의 소개 | 인프런

www.inflearn.com

 

반응형

댓글