@Value, @ConfigurationProperties에 대해서

2023. 12. 20. 20:45Springboot

0. 개요

       Spring boot의 환경 변수를 지정해서 사용할 때, lombok의 @Value를 사용하는 것이 좋은지

       또는 @ConfigurationPropreties를 사용하여 사용하는 것이 좋은지에 대한 의문에서 시작

       되었습니다.

 

1. @Value

     1) 환경 변수의 값을 단일으로 받아오기 위해서 사용합니다.

     2) RelaxedBinding이 적용이 되어 있지 않기에 완벽하게 일치하는 프로퍼티 이름을 적어줘야합니다.

     ** RelaxedBinding : 프로퍼티 값이 조금 달라도 유연하게 바인딩 시켜주는 규칙

# application.yml

spring : 
    jwt:
      secretKey: ${jwt.secret-key}
      access-token-expiration: 86400000  # 1시간
      refresh-token-expiration: 8467200000 # 14일
      
------------------------------------------------------
// jwtUtil.class
  
public class JwtUtil {
    // 수많은 코드들...
    @Value("${spring.jwt.secret-key}")
    private String secretKey
    // 수많은 코드들...
}

2. @ConfigurationProperties

     1) 프로퍼티에 있는 값을 클래스로 바인딩하기 위해 사용되는 어노테이션이다.

         해당 프로퍼티의 많은 값을 주입 받을 수 있게 해줍니다.

     2) RelaxedBinding도 적용이 가능, 카멜 케이스, propreties에 권장 표기법에

         적용되는 것을 유연하게 바인딩 시켜줌

         ** propreties 권장 표기법 : server.admin-what-is-real-name
         ** 표준 카멜 케이스 문법 : server.adminWhatIsRealName 

     3) Setter 필요, Constructor 바인딩 시에 @ConstructorBinding 붙어줘야함

         ** 이는 final 키워드의 필드를 가지고 오기 위해서 안 붙혀주면 
         ** 당연하게도 field를 못 가져옴

     4) @Validated 적용 가능

 

     ex) JwtProperties.java

     ** 해당 프로퍼티 클래스를 만들어서 @Value 어노테이션 없이 해당 값을 getter로 사용할 수 있다.

     ** application.yml은 위의 파일과 같음

package com.pjh.plusproject.Global.Config;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@Getter
@Validated
@RequiredArgsConstructor
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {

    private final String secretKey;
    private final Long accessTokenExpiration;
    private final Long refreshTokenExpiration;
}

 

public class JwtUtil {
    // 수 많은 코드들...
    public static final String BEARER_PREFIX = "Bearer ";
    public static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String REFRESH_TOKEN_HEADER = "RefreshToken";
    public static final String AUTHORIZATION_KEY = "auth";
    // private static final long TOKEN_TIME = 60 * 60 * 1000L;
    private JwtProperties jwtProperties;
    private Long accessTokenExpiration;						// 이 부분을 위해 가져옴
    private Long refreshTokenExpiration;					// 이 부분을 위해 가져옴
    private String secretKey;								// 이 부분을 위해 가져옴
    private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
    private Key key;
    
    @PostConstruct
    public void init(){
        log.info("init start!");
        secretKey = jwtProperties.getSecretKey();
        accessTokenExpiration = jwtProperties.getAccessTokenExpiration();
        refreshTokenExpiration = jwtProperties.getRefreshTokenExpiration();
        byte[] bytes = Base64.getDecoder().decode(secretKey);
        key = Keys.hmacShaKeyFor(bytes);
    }
    // 수 많은 코드들...
    
    public void setTokenForCookie(TokenDTO tokenDTO, HttpServletResponse respnose){
        String accessToken = URLEncoder.encode(BEARER_PREFIX + tokenDTO.getAccessToken(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        String refreshToken = URLEncoder.encode(BEARER_PREFIX + tokenDTO.getRefreshToken(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");

        Cookie accessTokenCookie = makeTokenCookie(AUTHORIZATION_HEADER, accessToken);
        Cookie refreshTokenCookie = makeTokenCookie(AUTHORIZATION_HEADER, refreshToken);

        respnose.addCookie(accessTokenCookie);
        respnose.addCookie(refreshTokenCookie);
    }
	// 수 많은 코드들...
}

 

3. 결론 

     1) @Value는 단일 값을 지정하기 위해 사용, @ConfigurationPropreties는 다중 값을 지정

          ** 프로젝트 사용할 때, 값을 환경 변수에 지정하는 경우가 많음으로

              @ConfigurationPropreties 사용 권장 

     2) @Value는 유연한 바인딩 x, @ConfigurationPropreties는 유연한 바인딩 o

 

     - 참고 : https://mangkyu.tistory.com/207

 

[Spring] @Value와 @ConfigurationProperties의 사용법 및 차이

Spring에서 프로퍼티에 있는 값을 불러오는 다양한 방법들이 있다. 이번에는 대표적인 방식인 @Value와 @ConfigurationProperties의 차이에 대해 알아보도록 하자. 1. @Value와 @ConfigurationProperties의 사용법 및

mangkyu.tistory.com