// 개발자가 제어
public class A {}
public class B {
private A a;
public B(){
this.a = new A();
}
}
// IoC Container(Spring) 제어
@Component
public class A {}
public class B{
private A a;
@Autowired
public B(A a){
this.a = a;
}
}
1번 코드의 경우 new 키워드를 사용하여 직접 객체를 생성 했지만, 2번 코드는 @Component와 @Autowired를 사용하여 new 키워드가 없음에도 객체가 생성되는 코드이다.
이처럼 개발자가 직접 객체를 관리 하는게 아닌 프레임워크에게 객체 생성 및 생명주기를 맡기는것이 제어의 역전이라 할 수 있다.
객체간의 의존관계를 직접 생성하는것이 아닌 IoC 컨테이너가 관리하는 Bean을 외부에서 주입받아 의존 관계를 형성하는 것을 DI, "의존성 주입"이라고 한다.
의존성 주입 방법에는 3가지가 있다.
@Component
public class A {}
// 생성자 주입
@Component
public class B {
private final A a;
@Autowired
public B(A a) {
this.a = a;
}
}
// Setter 주입
@Component
public class B {
private A a;
@Autowired
public void setA(A a) {
this.a = a;
}
}
// 필드주입
@Component
public class B {
@Autowired
private A a;
}
이 3가지 방법중 스프링에서 권장하는 방법은 생성자 주입이다.
생성자 주입
순환 참조 예방
불변성 보장
테스트의 편리함
Setter 주입
필드 주입