ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 여러 빈 중 빈을 선택해서(동적으로 빈을 선택하여) 서비스를 수행하고 싶을 때
    JAVA/Spring(Springboot) 2021. 7. 24. 15:49
    728x90
    728x90

    여러 개의 빈 중 선택해서 서비스를 수행하고 싶을 때는 어떻게 해야할까?

    그렇다면 빈을 모두 스프링 컨테이너에 저장한 후에 스프링 빈 이름으로 가져와서 사용하면 된다

     

     

     

    예제로 자세하게 살펴보자

     

     

     

    아래와 같이 할인 정책이라는 인터페이스가 있다

    RateDiscountPolicy 와 FixDiscountPolicy 는 이 할인 정책 인터페이스를 구현하고 있다

     

    사용자 중 한명은 RateDiscountPolicy 정책을 사용하고

    또 한명은 FixDiscountPolicy 을 사용해야한다면 어떻게 해야 할까?

     

     

     

     

     스프링 빈을 등록하는 설정정보를 생성한다.

    @Configuration 
    public class DiscountPolicyConfig {
        @Bean 
        public DiscountPolicy rateDiscountPolicy() {
        	return new RateDiscountPolicy();
        }
    
        @Bean 
        public DiscountPolicy fixDiscountPolicy() {
        	return new FixDiscountPolicy();
        }    
    }

    스프링 컨테이너에 RateDiscountPolicy,  FixDiscountPolicy 를 DiscountPolicy의 동일한 타입으로
    스프링 빈을 등록한다.

     

     

    static class DiscountService {
        private final Map<String, DiscountPolicy> policyMap;
    
        // 스프링 컨테이너에 저장됨
        @Autowired
        public DiscountService(Map<String, DiscountPolicy> policyMap) {
            this.policyMap = policyMap;
            System.out.println("policyMap = " + policyMap);
        }
        
        public int discount(Member member, int price, String discountCode) {
            DiscountPolicy discountPolicy = policyMap.get(discountCode);
    
            return discountPolicy.discount(member, price);
        }
    }

    policyMap에 RateDiscountPolicy,  FixDiscountPolicy 두 스프링 빈이 의존관계 주입이 된다.

     

    discountPolicy는 정책에 맞게 할인금액을 반환해주는 함수를 구현하고 있다

    discount() 함수를 사용할 때 discountCode(스프링 빈 이름)로

    policyMap에서 사용하고 싶은 정책을 가져와 사용할 수 있다  

     

    policyMap 을 print한 모습

    policyMap의 key에 스프링 빈의 이름이 들어간 것을 확인할 수 있다

     

     

     

     

    그리고 스프링 컨테이너를 생성해보자

    @Test
    void findAllBean() {
        AnnotationConfigApplicationContext ac
                = new AnnotationConfigApplicationContext(DiscountPolicyConfig.class, DiscountService.class);
    
        DiscountService discountService = ac.getBean(DiscountService.class);

     

     

    DiscountService에 원하는 스프링 빈의 이름을 파라미터로 넣어서 사용할 수 있다.

        Member member = new Member(1L, "userA", Grade.VIP);
    
        // fixDiscountPolicy 를 가지고 올 경우
        int discountPrice = discountService.discount(member, 10000, "fixDiscountPolicy");
        Assertions.assertThat(discountPrice).isEqualTo(1000);
    
        // rateDiscountPolicy 를 가지고 올 경우
        discountPrice = discountService.discount(member, 20000, "rateDiscountPolicy");
        Assertions.assertThat(discountPrice).isEqualTo(2000);
        
    }
    728x90
    728x90
Designed by Tistory.