Spring @Value Injection Error 해결 방법/ @Value 값이 주입되지 않아서 null로 뜨는 경우

Youngeui Hong·2022년 7월 28일
1

Spring

목록 보기
1/1
post-thumbnail

🤷🏻‍♀️ 오류 발생 상황

@Value를 사용하여 아래의 url 필드에 값을 주입하려고 했다.

@Component
public class AwsS3Proxy {
   //
   @Value(“${aws.s3.url:https://bucket.s3-ap-southeast-1.amazonaws.com})
   private String url;
}

그리고 주입될 값을 application.yml에 넣어주었다.

aws:
     s3:
         url: https://inject-value.com

그런데 값이 주입되지 않아서 null로 뜨는 문제가 발생하였다.

@Component 어노테이션을 붙여서 Bean으로 등록도 했고, application.yml에 해당되는 값도 넣어주었는데 왜 값이 주입되지 않았을까?

🤩 오류의 원인

원인은 @Value를 통해 값을 주입 받아야 하는 클래스가 컴포넌트 스캔 범위에 없었기 때문이다.

당시의 상황을 좀 더 자세히 살펴보자.

위의 그림을 살펴보면 @Value를 통해 값을 주입할 필드를 가지고 있는 AwsS3Proxy는 공통 라이브러리에 있는 클래스이다.

그리고 service라는 프로젝트는 공통 라이브러리를 사용하는 입장으로 application.yml을 통해 값을 주입해주는 곳이다.

이때 service 프로젝트가 컴포넌트를 스캔하는 범위는 com.heritage.service이다.

그런데 @Value로 값을 주입하고자 하는 클래스의 경로는 com.heritage.common.config이다.

이처럼 service 프로젝트가 컴포넌트를 스캔하는 범위에 해당 클래스가 없었기 때문에 application.yml에 값이 있어도 주입할 수 없었던 것이다.

🚀 오류 해결 방법

오류의 원인을 찾았으니 이제 컴포넌트를 스캔하는 범위에 해당 클래스를 추가해주면 될 것이다.

컴포넌트 스캔 범위는 어떻게 조정할 수 있을까?

아래와 같이 EnableAutoConfiguration을 사용하면 Spring에게 컴포넌트 스캔 범위를 알려줄 수 있다.

먼저 AwsS3Proxy를 Bean으로 등록해주는 Configuration 클래스를 작성한다.

@Configuration
@ComponentScan("com.heritage.common.config")
public class CommonConfiguration {
	@Bean
	public AwsS3Proxy awsS3Proxy() { return new AwsS3Proxy(); }
}

그 다음 main/resources 경로에 META-INF 디렉토리를 추가하고, 아래와 같이 작성한 spring.factories 파일을 넣어준다.

org.springframework .boot.autoconfigure.EnableAutoConfiguration =\
       com.heritage.common.config.CommonConfiguration

그러면 값이 정상적으로 주입되는 것을 발견할 수 있을 것이다.

👀 EnableAutoConfiguration? 조금 더 알아보자

프로젝트의 Entry point에는 @SpringBootApplication어노테이션을 붙여준다.

이 어노테이션을 타고 들어가보면 @SpringBootApplication은 아래와 같이 구현되어 있다.


@Target(value=TYPE)
 @Retention(value=RUNTIME)
 @Documented
 @Inherited
 @SpringBootConfiguration
 @EnableAutoConfiguration
 @ComponentScan(excludeFilters={@ComponentScan.Filter(type=CUSTOM,classes=TypeExcludeFilter.class),})
public @interface SpringBootApplication

즉, 다음 세 가지 어노테이션의 기능을 포함하고 있는 것이다.

  • @EnableAutoConfiguration
  • @ComponentScan
  • @Configuration

이 중 @EnableAutoConfiguration은 jar dependencies를 바탕으로 자동으로 Spring 환경을 설정해주는 어노테이션이다.

예컨대 classpath에 tomcat-embedded.jar가 있으면 TomcatServletWebServerFactory가 필요할 것으로 판단하여 자동으로 Bean으로 등록해주는 식이다.

관련하여 자세한 내용은 아래 공식문서에서 볼 수 있다.
Using the @SpringBootApplication Annotation

0개의 댓글