의존관계 주입

byeol·2022년 11월 24일
0

7.의존관계 주입

개발자가 직접 생성하는 것이 아니라 외부에서 의존성을 주입하는 것을 의존성 주입이라고 한다.

✔ 방법 5가지

  • 생성자 주입 : 생성자 호출 시점에 딱 1번만 호출되는 것 보장, 불변 및 필수 의존관계에 사용
  • 수정자 주입(setter) : 선택, 변경 가능성이 있는 의존관계, 자바빈 프로퍼티 규역의 수정자 메서드
    주입할 대상이 없으면 오류가 발생, 따라서 주입할 대상이 없을 경우 @Autowired(required=false)로 지정
  • 필드 주입 : 필드에 바로 주입, 코드 간결하나 외부에서 변경 불가능하여 테스트가 힘들며 DI 프레임워크에 의존 -> 사용하지 X

  • 일반 메서드 주입 : 한번에 여러 필드, 일반적으로 사용하지 X

✔ 옵션 처리 : 주입할 스프링 빈이 없을 때도 동작하도록->주입할 스프링 빈이 없으면 오류가 나는데 그 오류가 나지 않도록 하는 것이 옵션처리

  • @Autowired(required=false)로 지정 : 자동주입 대상이 없으면 수정자 메서드 자체가 호출 X
@Autowired(required = false)
public void setNoBean1(Member member) {
  • org.springframework.lang.@Nullable : null이 입력
@Autowired
public void setNoBean2(@Nullable Member member) {
  • Optional<> : Optional.empty이 입력
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {

✔ 생성자 주입을 선택하자!!

  • 불변
    대부분의 의존관계 애플리케이션 종료 전까지 변하면 안된다.
    -> 그러나 수정자 주입은 객채들을 public으로 열어두어여 한다.
    -> 누군가 실수로 변경하면 큰일
  • 누락
    수정자 주입의 경우 객체 누락의 경우 실행은 되나 null이 나옴
    그러나 생성자 주입은 컴파일 오류가 뜸 -> 즉 컴파일 오류로 오류를 잡을 수 있도록 해준다.
  • final 키워드
    생성자 주입은 객체에 final사용할 수 있다-> 값이 설정되지 않으면 컴파일 오류로 알려줌

✔ 롬복 : final이 붙은 필드를 모아 생정자를 자동으로 만들어 준다
순서 : 생성자 주입에서 생성자가 딱 1개 존재하는 경우 -> @Autowired생략->@RequriedArgsConstructor를 사용하여 생성자도 생략

@Component
@RequriedArgsConstructor
public class OrderServiceImpl implements OrderService {

   private final MemberRepository memberRepository;
   private final DiscountPolicy discountPolicy;

}

✔ 조회 빈이 2개 이상 즉 같은 타입의 빈이 2개 이상인 경우
@Autowired는 타입으로 조회화여 의존관계를 만든다.

해결방법

  • @Autowired 필드명 매칭
@Autowired
private DiscountPolicy rateDiscountPolicy
  1. 필드명 매칭
  2. 타입 매칭 결과가 2개 이상일 때, 필드명인 파라미터 명으로 빈이름 매칭
  • @Qualifier 사용

    만약 mainDiscountPolicy라는 Qualifier를 못 찾으면 저 이름을 가진 스프링 빈을 찾는다.
    그 스프링도 못 찾으면->NoSuchBeanDefinitionException 발생

  • @Primary 사용

    • 우선순위는 Qualifier가 더 높다.
  • 애노테이션 직접 만들기 : @Qualifier 사용의 경우 컴파일할 때 타입체크가 불가능

✔ 조회 빈이 2개 이상인데 조회한 빈이 모두 필요한 경우 List, Map
여러개일 때 사용자가 선택할 수 있도록 바꾸기

  • 이럴 경우 우리는 Map<String, DisscountPolicy>와 List를 필수 인자로 받는 생성자를 갖는 클래스 객체를 컴포턴트로 등록하고 생성자 의존관계 주입을 한다.

  • 중요한 것은 스프링 컨테이너에 2개 클래스에 있는 객체들을 담는 것이다.

    스프링 빈으로 담을 때 생성자 주입을 통해서 생성자가 생성되며 이게 스프링 빈에 담긴다.

  • 사용자로부터 입력을 받기 위해서 DiscountService에 메소드를 추가한다.

    discount() 메서드의 discountCode로 메시지가 넘어온다.
    policyMap이 Map이기 때문에 키값으로 객체를 선택할 수 있도록 구현됨

  • 사용자로부터 입력 받기

    ✔ 자동 VS. 수동

  • 자동을 선호하는 추세 그러나!
    기술 지원 로직(데이터베이스 연결이나 공통 로그 처리처럼 업무 로직을 지원하기 위한 하부 기술이나 공통기술)은 수동으로 한다. 왜냐하면 너무 광범위해서 어디서 문제가 발생하면 파악하기 어렵기 때문에 세심하게 관리한다.

  • 다형성의 경우 자동 등록 스프링 빈들은 같은 패키지에 수동등록은 같은 클래스에 두기

profile
꾸준하게 Ready, Set, Go!

0개의 댓글