의존 관계 주입 방법

min·2022년 5월 25일
0

다양한 의존관계 주입 방법

스프링 컨테이너 라이프 사이클
1. bean 등록
2. 연관 관계 자동 주입

생성자 주입

  • 생성자를 통해서 의존 관계 주입
  • 생성자 호출하는 시점에 딱 1번만 호출되는 것이 보장됨
  • 불변, 필수 의존 관계에 사용함
    * 불변: 의존 객체 변수 private으로 선언해주고 setter 없애서 외부에서 해당 변수를 변경하지 못하도록 해줌. 이를 통해서 스프링이 올라가면 MemberRepository는 평생 변경 할 수 없는 몸이 될 수 있다. 의존 관계는 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없다.
    • 필수: final 키워드를 통해서 필수로 값을 지정 할 수 있도록 설정 할 수 있다. 불변이기 때문에
  • 생성자가 1개만 있으면 @Autowired는 자동으로 붙어서 자동으로 의존 관계가 주입되는 것을 확인 할 수 있다.
  • 생성자 주입은 OrderServiceImpl 객체를 생성하면서 생성자를 호출 할 수 밖에 없기 때문에 bean 객체를 등록하면서 자동 주입이 된다...!
  • 순수한 자바 언어의 특징을 잘 살리는 방법이다.
	// 생성자를 통해서만 의존 관계가 주입 되기 때문에 외부에서 빈 주입을 할 수 없음
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
    
    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

롬복 라이브러리를 사용해서 좀 더 쉽게 제공 할 수 있다.

// final 변수를 바탕으로 생성자를 생성해주는 @RequiredArgsConstructor을 이용해서 생성자 주입 구현 가능

@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
}

수정자 주입(setter 주입)

  • setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존 관계를 주입하는 방법
  • 선택, 변경 가능성이 있는 의존 관계에서 사용함
    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    @Autowired
    public void setMemberRepository(MemberRepository memberRepository) {
        System.out.println("memberRepository = " + memberRepository);
        // MemberRepository가 final로 선언 되어 있으면 당연히 setter를 통해서 값을 변경 할 수 없다;
        this.memberRepository = memberRepository;
    }

    @Autowired
    public void setDiscountPolicy(DiscountPolicy discountPolicy)
    {
        System.out.println("discountPolicy = " + discountPolicy);
        this.discountPolicy = discountPolicy;
    }

필드 주입

  • 필드에 주입하는 방식
  • 코드가 간결해서 매우 유혹적이지만.. 외부에서 변경이 불가능해서 테스트 하기 힘들다는 치명적인 단점이 있다.
    * 우리; 회사는 테스트를;; 안쓰고 있으니까;; 그냥 막쓰는 경우가 많았구먼... 문득 스쳐 지나가는 끔찍한 코드들;;
  • DI 프레임워크가 없으면 아무것도 할 수가 없다.
  • 사용하지 말자!
  • 애플리케이션이랑 상관 없이 돌아가는 테스트 코드에서의 자동 주입, @Configuration의 경우에는 상관 없음

일반 메서드 주입

  • 일반적인 메서드를 통해서도 주입이 가능하긴 한데 잘 사용하지는 않는다.

의존관계 자동 주입은 스프링 컨테이너가 관리하고 있는 빈이어야지만 동작한다는 걸 명심하자..!

옵션 처리

  • 주입할 스프링 빈이 없어도 동작해야 하는 경우

조회되는 빈이 2개 이상인 경우?
1. @Autowired의 필드명을 특정 빈 이름으로 지정해준다.
2. @Qualifier를 이용해서 이름을 줘서 조회 해 준다.
3. @Primary를 이용해서 해당 빈들 사이의 우선 순위를 지정해준다.

보통 실무에선 어떻게 쓰나요?
메인으로 사용하는 bean에는 @Primary를 통해서 우선 순위를 주고 서브 bean의 경우에는 @Qulifier를 지정해줘서 사용함.
@Primary와 @Qulifer가 두 bean에 각각 지정되어 있다고 치면 사용하는 측에서는 @Qulifer에 지정된 bean이 좀 더 자세한 bean 지정이기 때문에 그를 따라감.


자동, 수동 빈 등록 유형

자동

  • 컨트롤러, 비즈니스 로직 서비스, 데이터 계층 관련 리포지토리와 같은 실제 업무와 관련된 로직

수동

  • 기술적인 문제, 공통적인 데이터베이스 연결, 로그 처리와 같은 업무 로직을 지원하기 위해 사용하는 기술 지원 빈들은 수동 빈으로 설정하여 설정 정보에 바로 나타나게 하는것이 좋음.
  • 비즈니스 로직 중에서 다형성을 적극적으로 활용한 경우 @Configuration 하위에 @Bean을 등록해서 한 눈에 확인하게 해주는 것이 좋기도 하다.
profile
발등에 불이 따뜻하다..

0개의 댓글