List, map형태의 Bean들
- 의도적으로 정말 해당 타입의 스프링 빈이 다 필요한 경우도 있다.
예를들어 할인 서비스를 제공하는데, 클라이언트가 할인의 종류(rate, fix)를 선택할 수 있다고 가정할 때 스프링을 사용하면 소위말하는 전략 패턴을 매우 간단하게 구현할 수 있다.
@Test
void findAllBean(){
ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class);
DiscountService discountService = ac.getBean(DiscountService.class);
Member member = new Member(1L, "userA", Grade.VIP);
int discountPrice = dircountService.discount(member, 10000, "fixDiscountPolicy");
assertThat(discountService).isInstanceOf(DiscountService);
assertThat(discountPrice).isEqualTo(1000);
}
static class DIscountService {
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policies;
@Autowired
public DiscountService(Map<String, DiscountPolicy> PolicyMap, List<DiscountPolicy> policies){
this.policyMap = policyMap;
this.policies = policies;
}
public int discount(Member member, int price, String discountCode){
DiscountPolicy discountPolicy = policyMap.get(discountCode);
return discountPolicy.discount(member, price);
}
}
- 위 코드중 대부분은 앞서 작성한 코드와 일치하나 주의깊게 살펴보아야할 부분은 바로 Bean을 Map 형태로 갖고있는 부분에서 fixDiscountPolicy라는 문자열로 getBean 메서드의 결과값들 중 get 메서드로 선택하여 바로 원하는 빈에 접근하는 흐름이 매우 중요하다.
- DiscountService는 DiscountPolicy 타입을 갖는 모든 Bean을 주입받는다.
- discountCode라는 문자열을 기반으로 주입받은 Bean중 일치하는 Bean을 찾아서 해당 Bean의 로직을 호출한다.