작성
·
31
0
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
setter메서드는 선택, 변경 가능성이 있는 의존계에 사용한다고 하셨는데
setter메서드에 @Autowired를 사용하더라도 스프링 컨테이너에 등록된 bean이 있어야 의존성 주입이 될텐데
그러면 제가 변경하고 싶은 구체 클래스에 @Component를 붙여서 다시 스프링 컨테이너에 등록을 해줘야 변경된 구체 클래스로 의존성 주입을 해주게 될텐데
그러면 생성자 주입과 다른 점이 어떤 것일까요???
선택, 변경 가능성이 있다는 의미가 순수 자바 코드로 테스트를 진행할 때 구체 클래스를 쉽게 변경할 수 있도록 하기 위함인 건가요???
답변 1
1
안녕하세요. hdh8990님
스프링에서 의존성을 주입하는 방식(생성자 주입, 필드 주입, setter 주입 등)은 모두 결국 스프링 컨테이너가 관리하는 Bean에 대해서만 주입이 이뤄진다는 점에서는 동일합니다. 그래서 “어차피 구체 클래스(Concrete Class)를 스프링 빈으로 등록해야 한다면, 생성자 주입과 뭐가 다른가?” 하는 의문이 생기실 수 있는데요. setter 주입을 사용하는 대표적인 이유와 그 특징을 정리해보면 다음과 같습니다.
생성자 주입은 빈이 생성되는 시점에 필수로 주입이 이뤄져야 합니다. 만약 해당 의존성이 없다면 빈 생성 자체가 불가능하게 되고, 이는 곧 애플리케이션 구동에 문제를 일으키게 됩니다.
setter 주입은 ‘필요하면’ 주입하도록 할 수 있습니다. 즉, 해당 의존성이 없더라도 빈 생성 자체가 가능하고, 상황에 따라 의존성을 주입하거나 주입하지 않을 수 있습니다.
- 예) 어떤 기능에서 의존성이 반드시 필요한 것이 아니고, 특정 옵션에 따라 추가로 주입해야 할 수도 있는 경우 등. (@Autowired의 경우에도 빈이 없는 경우 무시하는 옵션들이 있습니다.)
이처럼 “선택 혹은 변경 가능성이 있는 의존성”이라면, 꼭 객체 생성 시점에 의존성을 강제하지 않고 상황에 따라 주입을 결정할 수 있게끔 setter 주입을 고려해볼 수 있습니다.
생성자 주입을 사용하면, 객체가 생성된 후에 해당 의존성을 변경하거나 교체하기 위해서는 빈 자체를 새로 생성해야 합니다.
setter 주입을 사용하면, 이미 생성된 객체의 의존성을 필요에 따라 교체(재설정)할 수 있습니다. 스프링 컨테이너 입장에서는 잘 사용되지 않는 케이스지만, 순수 자바 코드 테스트나 특정한 환경에서 setXxx()
메서드를 직접 호출해 다른 구현체로 교체할 수 있다는 장점이 있습니다.
물론 스프링 컨테이너에서 실제로 의존성을 재주입하는 로직을 자주 쓰는 일은 드뭅니다.
생성자 주입의 경우, 테스트 코드에서 직접 객체를 만들어 테스트하려면 매번 해당 의존성들을 함께 생성해서 전달해야 합니다.
setter 주입을 사용하면, 테스트 코드에서는 new SomeService()
로 객체를 생성한 후, 필요한 의존성만 setXxx()
메서드를 통해 주입해줄 수 있습니다. 예를 들어 Mock 객체나 테스트 더블(Test double)을 쉽게 끼워 넣기 좋습니다.
특히 스프링 컨테이너를 거치지 않고 순수 자바 코드로 단위테스트를 작성할 때, setter 주입은 객체 생성 → setter 호출로 매우 단순한 패턴으로 테스트를 꾸릴 수 있습니다.
일반적으로는 생성자 주입을 권장합니다.
- 왜냐하면 빈 생성 시점에 필요한 의존성이 충족되지 않으면, 컴파일 시점에 바로 오류를 찾을 수 있기 때문입니다.
- 또한 불변(immutable)성을 확보할 수 있어 테스트와 유지보수에 유리합니다.
setter 주입은 “선택적 의존성”이거나, 런타임 중 의존성 변경이 필요한 특별한 경우에 사용을 고려합니다.
“선택, 변경 가능성”이라는 말은,
스프링 관점에서는 필수 의존성이 아니다라는 의미(즉, 필요하다면 주입, 아니라면 생략)를 내포할 수 있고,
테스트 관점에서는 순수 자바 코드에서 의존 객체를 쉽게 교체(주로 Mock) 할 수 있다는 것을 의미합니다.
따라서 “setter 메서드에 @Autowired를 쓰든, 생성자 주입을 쓰든 결국 스프링 빈으로 등록해야 하는 거 아닌가?”라는 질문에 대한 답은 예, 그렇습니다입니다. 하지만 주입 시점과 옵션 처리 유무, 테스트 편의성, 런타임 동적 변경 같은 부차적인 관점에서 두 방식이 서로 다른 장단점을 갖게 됩니다.
감사합니다.