생성자 주입

초보개발·2021년 12월 16일
0

Spring

목록 보기
20/37

생성자 주입의 필요성

최근에는 스프링을 포함해서 DI Framework 대부분들이 생성자 주입을 권장하고 있다.

1. 불변

  • 대부분의 의존관계 주입은 한 번 발생하면 애플리케이션 종료까지 의존관계를 변경할 일이 없다. 그리고 대부분의 의존관계는 애플리케이션 종료전까지 변경되면 안된다.
  • 수정자 주입을 사용할 시, setName 메서드를 public으로 지정해야 한다.
  • 실수로 변경할 수 있게 되거나 변경하면 안되는 메서드를 열어두는 것은 좋은 설계가 아니다.
  • 생성자 주입은 객체를 생성할 때, 딱 1번만 호출되기 때문에 이후에 호출될 일이 전혀 없다. 따라서 불변하게 설계 가능하다.

2. 누락

수정자 의존 관계가 아래와 같을 때, @Autowired가 프레임워크 내에서 동작할 때에는 의존관계가 없으면 오류가 발생하나 프레임워없이 자바 코드로만 단위 테스트를 수행하고 있다. 테스트를 진행하면 실행은 되지만, NPE가 발생하는데 그 이유는 memberRepository, discountPolicy가 의존관계 주입이 누락되었기 때문이다.

@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
}

@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy){
    this.discountPolicy = discountPolicy;
}

생성자 주입을 사용한다면 아래와 같이 주입 데이터를 누락했을 때 컴파일 오류가 발생하면서 어떤 값을 필수로 주입해야 하는지 바로 알 수 있게 된다.

@Test
void createOrder() {
    OrderServiceImpl orderService = new OrderServiceImpl();
    orderService.createOrder(1L, "A", 10000);
}

3. final 키워드

생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있다. 따라서 생성자에서 값이 할당되지 않았을 때, 컴파일 오류를 발생하여 막을 수 있다.

@Component
public class Exampleimpl implements Example {
    private final ClassA classA;
    private final ClassB classB;
    
    // classB에 값이 할당되지 않았으므로 오류 발생
    public Exampleimpl(ClassA classA, ClassB classB) {
        this.ClassA = classA;
    }
}

참고
수정자 주입을 포함한 나머지 주입 방식은 모두 생성자 이후에 호출되므로, 필드에 final을 사용할 수 없다. 생성자 주입만 final 키워드 사용이 가능하다.

0개의 댓글