본문 바로가기
기술/Spring-Boot

@Autowired는 왜 별로일까?

by Zabee52 2021. 11. 28.

@Autowired

 

스프링에서 의존성을 주입하는 방법은 여러가지가 있다.

의존성 주입이 뭔지 잘 모르겠다고? 이걸 보고오면 된다.

 

의존성 주입(DI)이 뭘까?

DI(Dependency Injection) 스프링 용어를 찾아보다보면 가장 먼저 접하고 매우 빈번하게 보게 되는 단어가 바로 DI다. 의존성 주입. 이게 대체 뭘 하는 녀석일까? 이것에 대해 설명하려면 IoC Container라는

dazbee.tistory.com

 

아무튼, 여러가지 방법 중, @Autowired는 필드 또는 메소드에 생성자를 자동으로 주입해주는 녀석이다. 근데, 이 편리한 기능. 쓰면 별로 안 좋다고 한다. 왜 그럴까?

 

결론부터 말하자면, 런타임 시점에 도달하기 전까지는 감지할 수 없는 문제가 발생할 수 있기 때문이다. 그게 뭐냐면 바로 순환참조(Circular reference)이다.

 

@Component
public class ClassA{
    @Autowired
    private final ClassB b;
    
    public void printB(){
    	b.print();
    }
}
@Component
public class ClassB{
    @Autowired
    private final ClassA a;
    
    public void printA(){
    	a.print();
    }
}

이렇게 서로를 참조하고 있는 상태에서 둘 중 하나를 호출하게 된다면 어떻게 될까?

ClassA 호출 -> ClassA 안의 ClassB 호출 -> ClassB 안의 ClassA 호출 -> ClassA 안의 ClassB 호출 -> ....

 

이런 과정을 통하다 결국 StackOverFlow 문제가 발생하게 된다.

 

느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, 느려, ...

이 문제는 해결할 수 있는 문제긴 하다. @Lazy라는 어노테이션을 사용하면 되는데, @Lazy 어노테이션은 사용되는 시점이 해당 빈이 필요한 시점이기 때문에 호출 과정에서 힙 메모리를 예정된 수준보다 많이 사용하게 될 수 있고, 메모리에 의한 장애로 이어질 수 있다.

 

 

결론을 말하자면, 해결은 가능한 문제지만, 곱게 생성자 주입 쓰자. 생성자 주입을 사용하면 어플리케이션이 구동되는 시점에서 문제를 확인할 수 있게 되기 때문에 훨씬 에러를 쉽게 체크할 수 있다. 게다가 Lombok을 쓰면 생성자를 귀찮게 만들어줄 필요도 없어진다. 여러모로 이게 편하다!

댓글