의도적으로 정말 해당 타입의 스프링 빈이 모두 필요한 경우가 생길 수 있다
-> 예를 들어, 할인과 관련된 서비스를 제공할 때 Client가 할인의 종류를 선택할 수 있다고 가정 (고정/비율)
스프링을 사용하는 경우 전략패턴을 매우 간단하게 구현할 수 있음
package hello.springintroduction.autowired;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import hello.AutoAppConfig;
import hello.springintroduction.Member.Grade;
import hello.springintroduction.Member.Member;
import hello.springintroduction.discount.DiscountPolicy;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
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 discountPrice = discountService.discount(member, 10000, "fixDiscountPolicy");
assertThat(discountService).isInstanceOf(DiscountService.class);
assertThat(discountPrice).isEqualTo(1000);
// AutoAppConfig에서 컴포넌트 스캔하면서 Rate, Fix DiscountPolicy를 스프링 빈으로 등록한다.
}
@Component
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; // Key Value
this.policies = policies; // Value
System.out.println("policyMap = " + policyMap);
System.out.println("policies = " + policies);
// 출력 결과 두 빈이 모두 등록됐으며 리스트로 등록되었음을 알 수 있다.
}
public int discount(Member member, int price, String discountCode){
DiscountPolicy discountPolicy = policyMap.get(discountCode);
System.out.println("discountCode = " + discountCode);
System.out.println("discountPolicy = " + discountPolicy);
return discountPolicy.discount(member, price);
}
}
}
참고로 타입이 같은 두 빈은 @Qualifer 또는 @Primary를 통해 우선순위나 빈이 지정되어 있는 상태에서 진행됨.
그렇지 않은 경우, 여기서도 NoUniqueBeanDefinition이 발생함.
전략패턴 구현을 위해 DiscountService에 Map과 List 형식으로 두 빈을 모두 가져온뒤
문자열을 통해 .get 한 이후, 해당 정책을 적용하는 과정을 거침
'스프링 공부 (인프런 김영한 선생님) > 스프링 핵심원리' 카테고리의 다른 글
[스프링 핵심원리] 9. @Autowired 필드명, @Qualifier, @Primary (0) | 2023.05.15 |
---|---|
[스프링 핵심원리] 8. 의존관계 자동 주입 (0) | 2023.05.15 |
[스프링 핵심원리] 7. Component Scan (0) | 2023.05.14 |
[스프링 핵심원리] 6. 싱글톤 컨테이너 (0) | 2023.05.10 |
[스프링 핵심원리] 5. 스프링 빈 조회 상속관계 BeanFactory와 ApplicationContext (0) | 2023.05.10 |