@Component
public class FixDiscountPolicy implements DiscountPolicy{ ... }
@Component
public class RateDiscountPolicy implements DiscountPolicy { ... }
다음과 같이 DiscountPolicy
를 상속받은 2개의 클래스가 빈으로 등록되어 있다고 가정한다.
@Autowired의 기본 조회 로직은 타입에 근거하기 때문에 위와 같이 2개의 빈이 조회가 되면 에러를 발생시킨다.
private DiscountPolicy rateDiscountPolicy;
@Autowired
public OrderServiceImpl(..., DiscountPolicy rateDiscountPolicy){
...
}
위와 같이 필드 명을 빈 이름으로 한다면 등록된 빈 중 필드 명과 같은 빈(RateDiscountPolicy
)을 주입한다.
@Component
@Quilifire("mainDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy{ ... }
private DiscountPolicy rateDiscountPolicy;
@Autowired
public OrderServiceImpl(...,
@Quilifier("mainDiscountPolicy") DiscountPolicy rateDiscountPolicy){
...
}
빈의 별칭을 만들고 의존성을 주입할 때 별칭을 찾아 주입한다.
하지만 주입하는 모든 코드에 별칭을 명시해야 하기 때문에 코드가 더러워진다.
@Component
@Primary
public class FixDiscountPolicy implements DiscountPolicy{ ... }
같은 타입의 빈 중에 우선순위를 매기는 어노테이션이다.
만약 여러 개가 조회되는 경우 @Primary 어노테이션이 붙은 빈이 선택된다.
중복 빈이 2개이고, 명확한 우선순위가 있는 경우 편리하게 사용할 수 있다.
이 경우 더 구체적인 별칭을 명시한 @Quilifier를 가진 빈이 선택된다.
할인 정책에 있어서 동적으로 런타임때 필요한 정책을 사용해야 한다는 상황일 때
class DiscountService{
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> discountPolicies;
@Autowired
public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> discountPolicies) {
this.policyMap = policyMap;
this.discountPolicies = discountPolicies;
}
public int discount(Member member, int price, String discountCode) {
DiscountPolicy discountPolicy = policyMap.get(discountCode);
return discountPolicy.discount(member, price);
}
}
생성자 컬렉션 파라미터 자동주입을 사용한다면
Map의 경우{fixDiscountPolicy=hello.core.discount.FixDiscountPolicy@73302995, rateDiscountPolicy=hello.core.discount.RateDiscountPolicy@1838ccb8}
,
List의 경우
[hello.core.discount.FixDiscountPolicy@73302995, hello.core.discount.RateDiscountPolicy@1838ccb8]
가 주입된다.
편하게 전략패턴을 구현할 수 있다.