Software Engineering Blog

컴퓨터공학부 3학년 재학 중인 학생입니다. 백엔드를 주로 공부하며 금융 분야에 관심이 많습니다.

Spring Boot

[Spring] Dependency Injection의 세 가지 방법

잔망준형 2024. 10. 14. 23:00

지금까지 나는 DI를 필드 주입을 통해서만 진행해왔다. (가장 간단하였기 때문이다..)

근데 DI에 대해 공부를 좀 하다 보니 필드 주입은 지양해야 되는 방법이라는 것을 알게 되었다.!

그러면 지금부터 왜 필드 주입은 지양해야 되는지, 그리고 나머지 의존성 주입 방법들은 무엇이 있는지 한번 알아보자.

결론부터 말하자면 생성자 주입을 사용하는 것이 정배이다.

의존성 주입의 세 가지 방법
  • 필드 주입 ( 비추천 )
  • 수정자 주입
  • 생성자 주입 ( 추천 )

왜 필드 주입은 별로인가?

필드 주입이란 그냥 @Autowired 애노테이션을 이용해서 스프링 IoC 컨테이너로부터 의존성이 주입되는 방식이다.

이거는 그냥 쓰지 말자. Spring 공식 문서에도 언급되지 않는 방법이다.

public class Controller {

	@Autowired
	private UserService userService;
}

위 방식이 필드 주입이다.

장점은 읽기에도 간결하고 쓰기에도 간결하다는 점이다.

근데 위 장점 말고는 문제점들이 많다.

  • 먼저, 테스트를 하기가 힘들다.
    • 필드 주입 방식은 Spring IoC 컨테이너로부터 주입을 받기 때문에 해당 컨테이너 없이 동작하지를 않는다.
  • 그리고 final 키워드를 사용할 수 없다.
    • 외부 메서드를 통해 의존 관계에 수정이 발생할 수 있다. 즉, 불변성을 보장받을 수 없다.
    • (의존 관계는 애플리케이션 실행 시에 한번 정해진 이후로 변경될 일도 없고 변경되어서도 안된다.)

그러면 나머지 방법은 뭐가 있을까?

 

수정자 주입과 생성자 주입이 존재한다.

수정자 주입

setter 메서드를 이용한 주입이다.

public Class Controller {
	
    private UserService userService;
    
    @Autowired
    public setUserService(UserService userService) {
    	this.userService = userService;
    }
}

 

앞선 필드 주입보다는 낫지만 이 방법도 여전히 문제점은 존재한다.

  • setter 주입이 되기 전에도 의존되는 객체가 생성될 수 있으므로 null이 참조될 경우가 생길 수 있다.
  • 여전히 final 키워드를 사용할 수 없기에 불변성을 보장받을 수 없다.
  • 그리고 setter 메서드가 public으로 열려있으므로 외부에서 의존성을 변경할 가능성도 존재한다.

생성자 주입

가장 추천되는 방식이다.

public Class Controller {
	
    private final UserService userService;
    
    @Autowired
    public Controller(UserService userService) {
    	this.userService = userService;
    }
}

final 지시어를 사용하여 한번 주입받은 의존성에 대해 불변성을 보장받을 수 있다.

또한 의존 객체가 없으면 애초에 생성이 되지 않기에 앞서 null을 참조하는 경우도 방지할 수 있다.

'Spring Boot' 카테고리의 다른 글

Spring과 Spring Boot에 대한 소개  (1) 2024.09.26
[Intellij] Gradle dependency(의존성) 추가 방법  (0) 2023.11.13