본문 바로가기
Spring

Spring - @Autowired를 쓰면 warning이 뜨는 이유

by 오늘부터개발시작 2022. 8. 16.

 

 

 

Warning

@Autowired 어노테이션을 사용하면 언제부턴가 IDE에서 불평을 내뱉으며 warning이 뜨게 된다. 그런데 막상 사용해보면 전혀 문제 없이 어플리케이션이 잘 작동하는 것을 알 수 있다. 그러면 도대체 어떤 이유 때문에 warning이 뜨는지 알아보도록하자. 

 

@Autowired란?

먼저 @Autowired 어노테이션이 어떤 역할을 하는지에 대해서 알아보도록하자. @Autowired는 의존성을 주입하기 위해 사용하는 어노테이션이다. 어노테이션 기반 환경이 나오기 전에 Spring에서는 xml 파일에 모든 Bean을 직접 등록하는 번거로움이 있었다. @Autowired가 나오고서부터는 클래스에 @Component라는 어노테이션을 붙여주고 사용할 때 간단하게 @Autowired만 사용하면 Spring Bean에 등록이 돼서 Spring이 의존성 주입을 해줄 수 있게 된다. XML 기반으로 개발했던 사람들에게는 엄청나게 편리하게 된 것이다.

 

@Autowired 사용방법

 

1. @Autowired와 클래스 사용

 

2. @Autowired와 Setter 사용

 

 

 

 

 

@Autowired의 문제점

그런데 @Autowired에는 문제가 생겨서 점차 사용을 권하지 않게되었다. 그 이유는 여러가지가 있겠지만 파악하고 있는 2가지를 공유해보고자한다.

 

1. NullPointException 가능성

@Autowired와 Setter를 함께 사용했을 때 NullPointException이 발생할 가능성이 있다. 그럴일은 거의 없겠지만 Setter로 의존성을 주입해줄 때 set을 까먹고 해주지 않을 가능성이 있다. 이 때 바로 사용하지 않는 로직이라면 사용할 때가 돼서야 NullPointError가 발생하는 것을 알 수 있다. 

 

2. 순환참조 방지 불가

Constructor를 사용하면 순환참조가 되었을 때(무한루프) 컴파일 타임에 에러가 발생한다. 다시 말하면 컴파일 타임에 안전하게 수정할 수 있다. 그러나 @Autowired 어노테이션을 사용하면 런타임에 에러가 나게 된다. 

 

 

그럼 어떻게 할까!?

Constructor 주입을 사용하자. Constructor 주입을 사용하면 @Autowired를 사용했을 때의 발생할 수 있는 문제점을 대부분 해결할 수 있다. 정리해보면 다음과 같다.

 

1. 의존성이 반드시 존재

Constructor로 초기화를 하면 반드시 디펜던시들이 주입 되어야만 초기화가 가능하다. 다시 말하면 컴파일 타임에 주입되지 않은 의존성을 잡아낼 수 있고 예상치 못한 NullPointerError를 방지할 수 있다.

 

2. 테스트 에러 방지

Constructor 주입은 unit test를 쉽게 할 수 있게 돕는다. Constructor는 의존성을 빠짐 없이 주입하도록 강제한다. 만약 class에 새로운 의존성을 추가했을 때 setter를 사용한다면 NullPointerException이 발생할 수 있지만 Constructor 주입을 사용하면 그럴 가능성이 없어진다.

 

3. 리팩토링 시사 

Constructor 주입을 사용하게 되면 너무 많은 디펜던시가 주입되는 것이 눈에 보인다. 객체지향 설계 원리에 따르면 각각의 객체들은 1개의 목적을 가질수록 좋다. 이렇게 눈에 띄게 의존성이 많으면 리팩토링을 해야함을 알 수 있다.

 

4. 불변성

Constructor 주입을 사용하면 최초에 생성할 때 의존성이 들어가고 그 후에는 변경이 불가능하다. 그러나 setter 주입을 사용하면 의존성이 런타임에도 바뀔수가 있게 된다.