객체간 의존성을 개발자가 객체 내부에서 직접 만들어 사용(new연산자)하는 대신, 외부 (스프링 컨테이너)에서 객체를 생성해서 넣어주는 방법이다.
@Controller
public class Controller{
private Service service;
@Autowired
public Controller(Service service){
this.service = service
}
}
생성자에 @Autowired를 붙여 의존성을 주입받을 수 있음.
Spring 4.3이후에는 클래스 내 생성자가 하나이고, 그 생성자로 주입받을 객체가 빈으로 등록되어 있다면 @Autowired
생략 가능
생성자 주입은 인스턴스 생성시 1회 호출되는 것이 보장되기 때문에, 주입받은 객체가 변하지 않거나, 반드시 객체주입이 필요한 경우 강제하기 위해 사용됨.
@Controller
public class Controller{
@Autowired
private Service service;
}
코드가 간결하고 편하지만 의존관계를 정확히 파악하기 힘듦.
필드 주입시 final 키워드를 선언할 수 없어 객체가 변할 수 있음.
주입이 동시에 일어나 겹치는 경우 순환참조 에러가 남.
@Controller
public class Controller{
private Service service;
@Autowired
public setService(Service service){
this.service = service;
}
}
setter 혹은 사용자 정의 메서드를 통해 의존관계 주입.
setter의 경우 객체가 변경될 필요성이 있을 때만 사용한다. (주입하는 객체를 변경하는 경우는 드물다)
스프링 팀에서는 생성자 주입을 권장한다.
객체의 생성자는 생성시 최초 1회만 호출되기에 주입받은 객체가 불변 객체여야 하거나 반드시 해당 객체의 주입이 필요한 경우 사용한다.
필드 주입으로 작성된 경우, 순수 자바 코드로 단위테스트를 실행하는 것이 불가하다. 메인코드는 Spring과 같은 DI프레임워크 위에서 동작하는데 단위테스트 시 단독적으로 실행되기 때문에 의존관계 주입이 null상태여서 NullPointerException이 발생하게 된다. 생성자 주입 시 단독으로 실행할 때도 의존관계 주입이 성립된다.
순환참조라 A객체는 B객체를 참조하고, B객체는 A객체를 서로 동시에 참조하고 있을 때 발생한다.