본문 바로가기
Dev/Spring Boot

[스프링 부트 개념과 활용] 외부 설정 2부

by dev_jsk 2020. 8. 24.
728x90
반응형

@Type-Safe Configuration Properties

같은 키로 시작하는 외부 설정이 많은 경우 설정들을 묶어서 하나의 Bean 으로 등록

// application.properties
// 같은 키(jsk) 로 된 설정을 묶어 하나의 Bean으로 등록 가능
jsk.name=Jinseo
jsk.age=${random.int(1,100)}
jsk.fullname=${jsk.name} Kim
// pom.xml
// dependency 추가
// 프로젝트 빌드 시 메타정보를 생성해 주는 플러그인
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
// JinseoProperties.java
@Component			// Bean 등록
@ConfigurationProperties("jsk")	// application.properties 바인딩
public class JinseoProperties {
    private String name;
    private int age;
    private String fullName;

    ... getter/setter
}

@ConfigurationProperties 가 선언된 클래스를 Bean으로 등록, 사용하기 위해선 @EnableConfigurationProperties@ConfiguraionProperties 가 선언된 클래스 목록을 넣어 Bean으로 등록하고 프로퍼티 값을 할당하지만 스프링 부트는 컴포넌트 스캔을 하므로 @Component 를 선언하면 자동으로 Bean으로 등록한다.

 

Bean으로 등록한 클래스는 다음과 같이 사용할 수 있다.

// SampleRunner.java
@Component
public class SampleRunner implements ApplicationRunner {
  // JinserProperties 를 Bean 등록했기 때문에 주입받아 사용할 수 있다.
  @Autowired
  JinseoProperties jinseoProperties;

  @Override
  public void run(ApplicationArguments args) throws Exception {
    System.out.println("===========");
    System.out.println(jinseoProperties.getName());
    System.out.println(jinseoProperties.getAge());
    System.out.println(jinseoProperties.getFullName());
    System.out.println("===========");
  }
}

 

외부 설정 특징

1. 융통성 있는(Relaxed) 바인딩

application.properties 내 키 값이 context-path(kebab) 이나 context_path(under score), CONTEXTPATH(upper case) 로 되어있어도 contextPath(camelCase) 로 변환하여 바인딩 한다.

// kebab
jsk.full-name=value
// under score
jsk.full_name=value
// upper case
jsk.FULLNAME=value

위 3가지 전부 camelCase 형태(fullName) 로 바인딩 된다.

 

2. Type Conversion 지원

properties 안에서는 Type 이 없다. 다 문자열로 작성되어 있지만 Bean 으로 등록될 클래스와 바인딩 할 때 각 Type 에 맞게 변환되어 바인딩된다.

 

@DurationUnit

스프링 부트가 제공하는 시간 정보를 제공하는 타입

// JinseoProperties.java
@DurationUnit(ChronoUnit.SECONDS)
private Duration sessionTimeout = Duration.ofSeconds(30);

// application.properties
jsk.sessionTimeout=25

추가적으로 @DurationUnit 을 생략하고도 외부 설정 값에 suffix 로 ns, ms, s, m, h, d 를 붙일 경우 Duration 타입으로 판단하여 프로퍼티 값을 바인딩 한다.

// JinseoProperties.java
private Duration sessionTimeout = Duration.ofSeconds(30);

// application.properties
jsk.sessionTimeout=25s

 

3. Property Value Validate

JSR-303 Validation Api의 구현체인 @Validated 를 이용한 프로퍼티 값 검증

// JinseoProperties.java
@Component
@ConfigurationProperties("jsk")
@Validated
public class JinseoProperties {
    
    @NotEmpty
    private String name;
    
    ...
}

// application.properties
jsk.name=
...
// Result
// Error Msg : FaliureAnalyzer 가 Error Msg 를 보기 좋게 만들어준다.
***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'jsk' to me.jsk.JinseoProperties failed:

    Property: jsk.name
	Value: 
    Origin: class path resource [application.properties]:2:0
    Reason: 반드시 값이 존재하고 길이 혹은 크기가 0보다 커야 합니다.


Action:

Update your application's configuration

다양한 어노테이션은 JSR-303 참고.

 

4. @Value VS @ConfigurationProperties

@Value

  • 정확한 키 값 작성 필요
  • 메타정보 미제공
  • Spring Expression Language 사용 가능

 

@ConfiguraionProperties

  • 프로퍼티 키값 자동완성 기능
  • Type Conversion
  • 프로퍼티 값 검증 가능
  • 융통성 있는 바인딩
728x90
반응형

댓글