반응형

스프링에서 같은 타입의 빈이 2개 이상이면 의존 주입이 실패하게 된다.
하지만 동적으로 빈을 변경해야 사용하고 싶을 경우가 있을 것이다.
예를 들어 어떤 로직에는 정률 할인 정책을 어떤 로직에는 고정 할인 정책을 사용하고 싶을 경우가 있다.
그런데 같은 타입이면 충돌이 나서 주입이 안되는데 어떻게 동적으로 처리할 수 있을까?

그 방법이 바로 전략 패턴을 활용한 컬렉션 사용이다. Map으로 활용 해보자.

생성자
→ 같은 타입의 모든 빈을 Map에 담는다. 같은 타입이 2개 이상이도 Map이기 때문에 주입이 가능하다.

discount()
→ String discountCode 파라미터가 전략 패턴을 사용한 코드이다.
클라이언트 코드에서 Map에 담긴 빈 중 원하는 빈을 이름으로 찾는 방법이다.

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

    public DiscountService(Map<String, DiscountPolicy> policyMap) {
        this.policyMap = policyMap;
    }

    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, 20_000, "rateDiscountPolicy");

        assertThat(discountService).isInstanceOf(DiscountService.class);
        assertThat(discountPrice).isEqualTo(2_000);
    }
반응형
복사했습니다!