ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring - 동일 타입의 빈이 2개 이상일 경우 의존관계 주입 방법
    Spring/Spring 2022. 1. 24. 12:32
    728x90
    반응형

     

    동일 타입의 빈이 2개 이상일 경우 의존관계 주입 시 오류가 발생

     

    @Component
    public class OrderServiceImpl implements OrderService {
    	private final MemberRepository memberRepository;
    	private final DiscountPolicy discountPolicy;
        
    	@Autowired
    	public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    		this.memberRepository = memberRepository;
    		this.discountPolicy = discountPolicy;
    	}
    }
    
    ...
    
    @Component
    public class FixDiscountPolicy implements DiscountPolicy {}
    
    ...
    
    @Component
    public class RateDiscountPolicy implements DiscountPolicy {}

     

     DiscountPolicy 타입의 빈이 스프링 컨테이너에 fixDiscountPolicyrateDiscountPolicy 2개가 등록 되어있다. 스프링은 의존관계를 주입할 때 컨테이너에서 해당 타입의 빈을 찾는데 위와 같은 경우는 DiscountPolicy 타입의 빈이 fixDiscountPolicyrateDiscountPolicy 2개가 발견이 된다. 때문에 스프링은 어느 빈을 주입할지 모르게 되어  NoUniqueBeanDefinitionException 예외가 발생한다. 

     

     이 때, 주입받고자 하는 필드를 하위타입(fixDiscountPolicyrateDiscountPolicy)으로 변경하여 원하는 빈을 주입받아도 되긴 하지만 이렇게 되면 DIP를 위배하게 되어 유연성이 떨어지게 된다. 

     


     

     

    동일 타입의 빈들 중 특정 빈을 주입받는 방법

     

    @Autowired

     

    • 주입받는 필드의 필드 명이나, 파라미터 명으로 빈 이름을 매칭

     

    // 필드 주입시 방법
    @Autowired
    private final MemberRepository rateDiscountPolicy;
    
    // 생성자 주입시 방법
    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) {
    	this.memberRepository = memberRepository;
    	this.discountPolicy = discountPolicy;
    }

     

     우선 주입받는 필드 타입과 일치하는 빈을 컨테이너에서 찾는다. 만약 일치하는 빈이 여러 개일 경우 필드의 필드 명이나, 파라미터 명으로 빈 이름을 찾아서 주입해준다.


     

    @Qualifier

     

    • 추가 구분자를 붙여주는 방법
    • 주의할 점! 빈 이름을 변경하는 것이 아닌 추가적인 방법(추가 구분자)를 제공하는 것이다.

     

    @Component
    @Qualifier("mainDiscountPolicy")
    public class RateDiscountPolicy implements DiscountPolicy {}
    
    @Component
    @Qualifier("fixDiscountPolicy")
    public class FixDiscountPolicy implements DiscountPolicy {}
    
    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository,@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
    	this.memberRepository = memberRepository;
    	this.discountPolicy = discountPolicy;
    }

     

     

    @Primary

     

    • 같은 타입의 여러 빈들이 존재할 경우 @Primary를 이용하면 우선권을 갖도록 할 수 있다.

     

    @Component
    @Primary
    public class RateDiscountPolicy implements DiscountPolicy {}
    
    @Component
    public class FixDiscountPolicy implements DiscountPolicy {}
    
    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository,DiscountPolicy discountPolicy) {
    	this.memberRepository = memberRepository;
    	this.discountPolicy = discountPolicy;
    }

     

     위 코드를 보면 rateDiscountPolicy 빈이 @Primary를 이용하여 우선권을 갖게 되었다. 주입할 때 동일 타입의 빈들이 컨테이너에 있어도 우선권을 갖고 있는 rateDiscounpolicy 빈이 있기 때문에 예외가 발생하지 않고 주입이 잘 이루어진다.

     

     만약 fixDiscountPolicy 빈을 주입하고자 하려고 한다면 어떻게 하면 될까?
    위에서 배운 @Qulifier를 이용하면 된다. 

     

     

     

     

     

     

     

    728x90
    반응형

    댓글

Designed by Tistory.