조회한 빈이 모두 필요할때

ttaho·2023년 3월 30일
0

Spring 기초

목록 보기
11/11

만약 할인 서비스를 제공하는데, 클라이언트가 할인의 종류(rate, fix)를 선택할 수 있다고, 가정하면 두가지 할인방법을 모두 가져와야 한다. 스프링을 사용하면 전략패턴을 매우 간단하게 구현할 수 있다.
우선 이를위한 테스트를 만든다.

package hello.core.autowired;

import hello.core.AutoAppConfig;
import hello.core.discount.DiscountPolicy;
import hello.core.member.Grade;
import hello.core.member.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.List;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

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 discountPrice1 = discountService.discount(member, 20000, "fixDiscountPolicy"); //discountCode에 변동할인인지 고정할인인지 표시를함.

        assertThat(discountService).isInstanceOf(DiscountService.class);
        assertThat(discountPrice1).isEqualTo(1000);

        int discountPrice2 = discountService.discount(member, 20000, "rateDiscountPolicy"); //discountCode에 변동할인인지 고정할인인지 표시를함.
        assertThat(discountPrice2).isEqualTo(2000);
    }


    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;

            System.out.println("policyMap = " + policyMap);
            System.out.println("policies = " + policies);
        }

        public int discount(Member member, int price, String discountCode) {
            DiscountPolicy discountPolicy = policyMap.get(discountCode);
            return discountPolicy.discount(member, price);
        }
    }
}

로직 분석

  • DiscountService는 Map으로 모든 DiscountPolicy를 주입받는다. 이때 fixDiscountPolicy, rateDiscountPolicy가 주입된다. 단, 두 구현체에 모두 @Component 애노테이션을 달아줬어야 한다.
  • discount() 메서드는 discountCode로 fixDiscountPolicy, rateDiscountPolicy라는 이름의 빈으로 등록되어 있을 것이므로 두개중 하나를 입력해주면, 이게 넘어와서 map에서 해당하는 스프링 빈을 찾아서 실행한다.
  • 해당하는 할인정책에 맞게 discount로 할인금액을 리턴한다.

주입 분석

  • Map<String, DiscountPolicy> : map의 키에 스프링 빈의 이름을 넣어주고, 그 값으로 DiscountPolicy타입으로 조회한 모든 스프링 빈을 담아준다.
  • List(DiscountPolicy) : DiscountPolicy 타입으로 조회한 모든 스프링 빈을 담아준다.
  • 만약 해당하는 타입의 스프링 빈이 없으면, 빈 컬렉션이나 Map을 주입한다.
profile
백엔드 꿈나무

0개의 댓글