생성자 주입을 사용하는 이유

Moon·2022년 6월 16일
post-thumbnail

의존관계 주입은 크게 4가지 방법이 있다.

  • 생성자 주입
  • 수정자 주입 (setter 주입)
  • 필드 주입
  • 일반 메서드 주입

👉 과거에는 수정자 주입이나 필드 주입을 많이 사용했으나 최근에는 생성자 주입을 권장하고 있다.

그 이유는 크게 두 가지인데 불변누락 이다.


불변

대부분의 의존관계 주입은 한 번 일어나면 애플리케이션 종료 시점까지 변경할 일이 없고 변하면 안 된다. 그런데 수정자 주입을 사용하는 경우에는 set~ 메서드를 public으로 생성하기 때문에 누군가 실수로 변경할 수도 있다. (변하면 안되는 메서드를 public으로 열어두는 것은 좋지 않다.)

생성자 주입은 객체 생성시 딱 한 번만 호출되기 때문에 이후에 호출되는 일이 없어 불변하게 설계할 수 있다.

누락

프레임워크 없이 순수 자바 코드를 단위테스트 하는 경우를 보자.

  • setter를 만든는 수정자 의존 관계의 경우에는 @Autowired가 프레임워크 안에서 동작하지 않기 때문에 의존관계가 없다고 오류가 발생하지 않는다. (프레임 워크 안에서는 오류가 발생함)
public class OrderServiceImpl implements OrderService {

    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;


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

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

테스트도 실행은 가능하나 의존관계 주입이 누락되었기 때문 NullPointException이 발생한다.

  • 생성자 주입을 사용하면 주입 데이터가 누락됐을 때 자바 컴파일러가 오류를 알려준다. (컴파일 오류 발생) 테스트를 실행하기 전에 IDEP에서 어떤 값을 필수로 주입해야 하는지 알 수 있기 때문에 시간을 절약할 수 있다.



final 키워드 사용하기

생성자 주입을 사용하면 final 키워드를 사용할 수 있다. 값이 설정되지 않는 오류를 컴파일 시점에 막아준다.

필수 필드인 memberRepository와 discountPolicy의 값을 설정하는 부분이 누락되었을 때 그냥 private을 사용하면 IDE에서 바로 알 수 없다.

값을 넣어주지 않아도 테스트 코드를 작성할 때까지 알 수가 없고 테스트를 실행하면 NullPointException이 나면서 값이 들어오지 않았다는 걸 알게된다.

final키워드를 사용하면 생성자에서 값이 설정되지 않는 오류를 컴파일 시점에 막아준다. (IDE에 바로 오류가 뜨기 때문에 빨리 발견할 수 있다.)

참고)
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8

profile
매일 성장하는 개발자 되기😊

0개의 댓글