[Spring] 특정 타입의 빈을 동적으로 가져오는 방법

728x90

 

특정 타입의 빈을 동적으로 가져오는 방법

class DiscountService {

  private final Map<String, DiscountPolicy> policyMap;
  private final List<DiscountPolicy> policies;

  public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policies) {
    this.policyMap = policyMap;
    this.policies = policies;
    System.out.println("policyMap = " + policyMap);
    System.out.println("policies = " + policies);
  }
  /**
  policyMap = {rateDiscountPolicy=RateDiscountPolicy@xxxx, fixDiscountPolicy=FixDiscountPolicy@yyyy}
  policies = [RateDiscountPolicy@xxxx, FixDiscountPolicy@yyyy]
  **/

  public int discount(Member member, int price, String discountCode) {
    DiscountPolicy discountPolicy = policyMap.get(discountCode);
    return discountPolicy.discount(member, price);
  }
}
@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 = discountService.discount(member, 10000, "fixDiscountPolicy");
  
  assertThat(discountService).isInstanceOf(DiscountService.class);
  assertThat(discountPrice).isEqualTo(1000);
}

우선 DiscountPolicy 타입인 클래스가 RateDiscountPolicy, FixDiscountPolicy 2개 있다고 가정하자.

그러면 `new AnnotationConfigApplicationContext()` 를 생성하며 `AutoAppConfig` 와 `DiscountService` 가 스프링 빈으로 등록된다.

 

DiscountService 의 @Autowired 가 실행되며 (위에서는 생성자가 1개라 @Autowired 가 생략되었다.)

`DiscountPolicy` 타입을 가진 스프링 빈을 찾는다.

`AutoAppCongfig`에서 스프링 빈을 등록하며 생성된 스프링 빈 저장소에서 `DiscountPolicy` 타입인 `RateDiscountPolicy`와 `FixDiscountPolicy` 를 찾는다.

`policyMap` 은 DiscountPolicy 타입의 모든 스프링 빈이 Map 형태로 주입되며,

`policies` 는 DiscountPolicy 타입의 모든 스프링 빈이 List 형태로 주입된다.

 

따라서 전략 패턴(Strategy Pattern)과 유사한 방식으로 원하는 빈을 선택해서 사용할 수 있다.

 

 

 

 

 

 

출처 | 스프링 핵심 원리 - 기본편(김영한) - 인프런

728x90