생성자 주입 방식
을 사용하는 이유를 정리합니다.
@Component
// @RequiredArgsConstructor // delombok
public class BComponent {
private final AComponent aComponent;
public BComponent(AComponent aComponent) { // parameter를 받음
this.aComponent = aComponent;
}
}
일단 생성자주입 방식외에 parameter를 받으므로써 자바는 객체를 주입한다.
자바에서는 객체를 주입하는 방법이 파라미터를 받는 방법 밖에 없다.(토비의 스프링 vol1.0)
그렇다면 왜 setter, 메서드 방식 등 다른 방법 외에 생성자 주입방식을 권고하는 걸까?
(스프링team에서는 spring4.0부터 생성자주입 방식을 권장한다.)
객체를 생성하는 시점에에 의존성이 생성된다.
의존성이 숨겨져 있으면 그 클래스 안에 직접 살펴볼 수 밖에 없다. 숨겨진 의존성 방식은 별로다. 생성자주입 방식은 인자를 명시적으로 볼 수 있다.
의존관계를 설정하는 부분과 시스템을 돌아가게하는 부분은 분리되어야 한다. (CleanCode)
변경 가능성을 최소화하라. (Effective Java)
수정자 주입을 사용하려면 setter 를 public 으로 열어야한다.
객체의 상태가 변경가능하면 문제가 생길 여지가 너무 많다.
생성자 주입은 빈이 등록되기위해
싱글톤 객체가 생성될 때 딱 한번만 주입하고 변경하지 않는다.
생성자 주입은 생성자의 매개변수로 주지 않으면 애초에 컴파일에러가 난다.
또, IDE 의 도움을 받으면 코드 작성시 매개변수를 볼 수 있다.
수정자 주입에서는 의존관계가 무엇이 있었는지 있긴 한지는 코드의 setter 를 까봐야한다.
또한 런타임에 에러가 나게 된다.
생성자 주입방식을 쓰면 final 을 쓸 수 밖에 없다.
필드에 final 을 쓰면 생성자나 필드 선언시에 초기화를 해야한다. 안그러면 컴파일에러다.
따라서 의존관계 주입 로직을 누락하는 실수를 방지할 수 있다.
앵간하면 생성자 주입을 쓰고, 특수한 상황에서는 setter(수정자) 주입을 쓰자.
필드 주입은 테스트하기 어려운 등 단점이 존재하여 Intellij 에서도 되도록 쓰지말라고 경고를 띄운다.
롬복의 이 기능을 쓰면 final 이 붙은 필드로 생성자를 한개 만들어준다.
생성자가 하나만 있으면 @Autowired 가 자동으로 붙는 것을 이용할 수 있다.
생성자를 하나만 두고 @Autowired 를 생략하는 방법을 많이 쓰기 때문에,
롬복까지 이용하여 생성자를 하나 만드는 @RequiredArgsConstructor 어노테이션을 사용하면, 코드가 매우 깔끔해진다.
https://alkhwa-113.tistory.com/entry/생성자-자동-주입의-장점 [기(술) 블로그]