필요한 의존성을 어떻게 받아올 것인가
다음 코드에서는 OwnerRepository 의존성을 생성자를 통해 주입받고 있다.
private final OwnerRepository owners;
public OwnerController(OwnerRepository owners) {
this.owners = owners;
}
생성자를 이용해 레퍼런스를 받은 다음, 다른 레퍼런스로 바뀌지 않는 것을 보장하기 위해서 final을 붙이면 좋다.
그런데 원래, 다음과 같이 생성자에 @Autowired를 붙여야 스프링이 자동으로 주입해줄 것 아닌가?
private final OwnerRepository owners;
@Autowired
public OwnerController(OwnerRepository owners) {
this.owners = owners;
}
스프링 4.3부터 클래스에 생성자가 하나 뿐이고, 생성자로 주입받는 레퍼런스 변수들이 빈으로 등록되어 있다면 그 빈을 자동으로 주입해주게 되었다.
따라서 @Autowired를 생략할 수 있는 것이다.
스프링에서 권장하는 방법은 이처럼 생성자를 이용하는 것인데,
필수적으로 사용해야 하는 레퍼런스 없이 해당 인스턴스를 만들지 못하도록 강제할 수 있기 때문이다.
그러나 순환참조(Circular Dependency)가 발생하는 경우,
생성자를 이용한 주입 방법은 교착 상태에 빠질 수 있기 때문에
생성자 주입 대신 필드 주입이나 Setter 주입을 통해 일단 인스턴스를 생성하고, 그다음 주입받도록 할 수 있다.
그러나 가급적이면 순환참조가 발생하지 않도록 하는 것이 좋겠다.
위 코드를 다음과 같이 고치면 의존성을 필드로 바로 주입받을 수 있다.
@Autowired
private final OwnerRepository owners;
혹은, Setter에 @Autowired를 붙이는 방법도 있다.
private OwnerRepository owners;
@Autowired
public void setOwners(OwnerRepository owners) {
this.owners = owners;
}