의도적으로 해당 타입의 스프링 빈이 다 필요한 경우도 있다. 예를들어, 할인 서비스를 제공하는데, 클라이언트가 할인의 종류(rate,fix)를 선택할 수 있다고 가정해 보자. 스프링을 사용하면 소위 말하는 전략 패턴을 매우 간단하게 구현할 수 있다.
1) 모든 빈 조회
public class AllBeanTest {
@Test
void findAllBean(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class);
}
static class DiscountService{
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policyList;
public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policyList){
this.policyMap = policyMap;
this.policyList = policyList;
System.out.println("policyMap = " + policyMap);
System.out.println("policyList = " + policyList);
}
}
}
출력결과
2) DiscountService 클래스의 생성자를 통해 여러 할인 정책을 받아들이고, 주어진 할인 코드에 따라 적절한 할인 정책을 적용
public class AllBeanTest {
@Test
void findAllBean(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class);
DiscountService discountService = ac.getBean(DiscountService.class);
Member member = new Member(1L,"UserA", Grade.VIP);
int fixDiscountPolicy = discountService.discount(member,10000,"fixDiscountPolicy");
assertThat(discountService).isInstanceOf(DiscountService.class);
assertThat(fixDiscountPolicy).isEqualTo(1000); //fix 테스트
int rateDiscountPolicy = discountService.discount(member,20000,"rateDiscountPolicy");
assertThat(rateDiscountPolicy).isEqualTo(2000); //rate 테스트
}
static class DiscountService{
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policyList;
//@Autowired 생략함
public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policyList){
this.policyMap = policyMap;
this.policyList = policyList;
System.out.println("policyMap = " + policyMap);
System.out.println("policyList = " + policyList);
}
public int discount(Member member, int price , String discountCode) {
DiscountPolicy discountPolicy = policyMap.get(discountCode);
return discountPolicy.discount(member,price);
}
}
}
로직 분석 1) DiscountService는 map으로 모든 DiscountPolicy를 주입 받는다. 이때 "fixDiscountPolicy","rateDiscountPolicy"가 주입된다. 2) discount() 메서드는 discountCode로 만약 "fixDiscountPolicy"가 넘어오면 map에서 fixDiscountPolicy 스프링빈을 찾아서 실행한다. "rateDiscountPolicy"의 경우도 동일하다
주입 분석 1) Map<String, DiscountPolicy> : map 의 키에 스프링 빈을 모두 넣어주고 , 그 값으로 DiscountPolicy타입으로 조회한 모든 스프링 빈을 담는다. 2) List<DiscountPolicy> : DiscountPolicy 타입으로 조회한 모든 스프링 빈을 담아준다. 3) 만약 해당하는 타입의 스프링 빈이 없으면 , 빈 컬렉션이나 map을 주입한다.