🌱Spring:: 'DI'란?(Dependency Injection, 의존성 주입)
Dependency, 의존관계란?
“A가 B를 의존한다.”는 표현은 어떤 의미일까. 토비의 스프링에서는 다음과 같이 정의한다.
의존대상 B가 변하면, 그것이 A에 영향을 미친다.
- 이일민, 토비의 스프링 3.1, 에이콘(2012), p113
즉, B의 기능이 추가 또는 변경되거나 형식이 바뀌면 그 영향이 A에 미친다.
Dependency Injection은?
의존관계를 외부에서 결정하고 주입하는 것이 DI(의존관계 주입)이다.
토비의 스프링에서는 다음의 세 가지 조건을 충족하는 작업을 의존관계 주입이라 말한다.
클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스만 의존하고 있어야 한다.
런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제3의 존재가 결정한다.
의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공(주입)해줌으로써 만들어진다.
- 이일민, 토비의 스프링 3.1, 에이콘(2012), p114
최근에는 Spring을 포함한 DI 프레임워크의 대부분이 여러가지 의존성 주입 방법 중 생성자 주입을 권장하고 있다.
DI 구현 방법?
1. 생성자 주입(Constructor Injection)
생성자를 통해 의존 관계를 주입하는 방법이다. 생성자 주입은 생성자의 호출 시점에 1회 호출 되는 것이 보장된다. 그렇기 때문에 주입받은 객체가 변하지 않거나, 반드시 객체의 주입이 필요한 경우에 강제하기 위해 사용할 수 있다. 또한 Spring 프레임워크에서는 생성자 주입을 적극 지원하고 있기 때문에, 생성자가 1개만 있을 경우에 @Autowired를 생략해도 주입이 가능하도록 편의성을 제공하고 있다.
@Component
public class MadExample {
// final로 선언할 수 있는 보너스
private final HelloService helloService;
// 단일 생성자인 경우는 추가적인 어노테이션이 필요 없다.
public MadExample(HelloService helloService) {
this.helloService = helloService;
}
}
2. 수정자 주입(Setter 주입, Setter Injection)
수정자 주입(Setter 주입, Setter Injection)은 필드 값을 변경하는 Setter를 통해서 의존 관계를 주입하는 방법이다. Setter 주입은 생성자 주입과 다르게 주입받는 객체가 변경될 가능성이 있는 경우에 사용한다. (실제로 변경이 필요한 경우는 극히 드물다.)
@Component
public class MadExample {
private HelloService helloService;
@Autowired
public void setHelloService(HelloService helloService) {
this.helloService = helloService;
}
}
3. 필드 주입(Field Injection)
필드 주입은 외부에서 접근이 불가능하다는 단점이 존재하는데, 테스트 코드의 중요성이 부각됨에 따라 필드의 객체를 수정할 수 없는 필드 주입은 거의 사용되지 않게 되었다. 또한 필드 주입은 반드시 DI 프레임워크가 존재해야 하므로 반드시 사용을 지양해야 한다.
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private MemberService memberService;
}
참고::
https://mangkyu.tistory.com/125
https://tecoble.techcourse.co.kr/post/2021-04-27-dependency-injection/