Having

static 필드에 @Value가 동작하지 않는 이유 본문

gift-card-flea-market

static 필드에 @Value가 동작하지 않는 이유

GHM 2023. 8. 1. 17:47

◈ 목차

  • @Value이란?
  • 에러 발생 과정
  • 발생 에러
  • 원인 (static 필드에 @Value가 동작하지 않는 이유)
  • 해결 방법

 

# @Value이란?

@Value는 Spring 애노테이션으로, 설정 파일 또는 환경 변수의 값(value)스프링 빈 필드로 주입하는데 사용됩니다.

## @Value을 사용할 때, @Autowired 떠올리기 !

@Autowired는 ApplicationContext에 빈으로 등록이 되어야만 의존관계 주입이 가능하듯이, @Value도 스프링 빈으로 등록이 되어야 application.properties(.yml)의 값을 주입받을 수 있습니다. 그렇기 때문에, @Value 애노테이션을 사용하는 클래스는 컴포넌트 스캔의 대상이 되는 애노테이션(@Controller/Service/Repository/Component 등)을 가져야 동작합니다.

 

 

@Value는 '필드, 메서드, 메서드 or 생성자 파라미터' 에 사용할 수 있으며,

사용법은 아래와 같이 두가지 입니다. 

  1. property placeholder : ${ncp.access-key}
    • Spring boot는 기본적으로 PropertySourcePlaceholderConfigurer를 스프링 빈으로 등록합니다. 때문에 아무런 설정 없이 application.properties or application.yml의 프로퍼티 값을 ${}로 가져올 수 있습니다. 
  2. SpEL : #{ncp.access-key}

# 에러 발생 과정

프로젝트의 SMS 인증 기능으로 Naver Cloud Platform의 서비스를 사용하고 있기 때문에 네이버 외부 API를 호출해야 합니다. 이때 사용되는 acceesKey, secretKey 등의 정보를 외부에 노출시키지 않게 하기 위해, 클래스 내의 변수로 값을 가지는 것 대신 설정 파일인 application-secret.yml에 값을 저장해두었습니다. @Value가 동작하도록 해당 util 클래스에 @Component 사용 !

 

애플리케이션을 구동시키고 SMS 인증 기능을 실행하면,

아래의 accessKey, secretKey는 application-secret.yml의 값을 가져오지 못하고 null을 가집니다.

accessKey, secretKey 모두 null

# 발생 에러

해당 두 필드를 사용하는 static method에서 NPE 발생

# 원인

스프링은 static 필드에 @Value를 지원하지 않습니다.

 

static 필드는 jvm 클래스 로더에 의해 jvm의 메모리 영역 중 하나인 Class Area(=Static Area, Method Area)에 런타임에 저장됩니다. 이 시점은 스프링 컨테이너인 ApplicationContext가 로드되기 전이므로, static 필드는 ApplicationContext에 의존적인 @Value가 동작하지 않습니다. (@Autowired도 동일)

 

# 해결 방법

setter 수정자 메서드를 사용하면 static 변수에 프로퍼티 값을 주입할 수 있다.

주의할 점은 static 메서드 아닌 setter !

 

 

 

 

 

참고 :
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Value.html

https://docs.spring.io/spring-framework/reference/core/beans/annotation-config/value-annotations.html