이전 포스팅에 이어, 타입 하나에 여러 빈이 등록이 될 수 있는데 그 빈이 모두 필요할땐 어떻게 다뤄야 하는지를 작성하려고 한다.
예를 들면 이런 경우를 보자.
유저가 선택한 할인 정책에 따라, 고정 할인과 비율 할인을 둘 다 사용할 경우가 있을 수 있다. 그러니까 서비스 자체적으로 정책을 결정하는게 아니고 유저가 선택한 할인 정책에 따라 할인을 해주는 서비스가 있을 수 있다. 그땐 둘 다 필요하다. 이런 경우에는 List, Map을 사용할 수 있다.
DiscountService
static 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);
}
}
위 코드를 보자. 생성자 주입을 통해 DiscountPolicy 빈을자동 주입하려고 한다.
근데 2개 이상인 경우 이렇게 Map 또는 List로 받으면 된다. (참고로, 둘 중 하나를 사용하면 된다. 그냥 둘 다 가능하다는 것을 보여주기 위해 작성한 것 뿐이다)
실행 결과를 보면 다음과 같이 잘 들어간다.
실행결과
policyMap = {fixDiscountPolicy=org.example.springcore.discount.FixDiscountPolicy@5f9be66c, rateDiscountPolicy=org.example.springcore.discount.RateDiscountPolicy@3abada5a}
policies = [org.example.springcore.discount.FixDiscountPolicy@5f9be66c, org.example.springcore.discount.RateDiscountPolicy@3abada5a]
그래서 둘 다 필요한 경우엔 어떻게 담는지를 알아봤고, 이렇게 둘 다 가져왔을 때 그때 그때 상황에 맞게 사용하는 코드를 작성해서 테스트 해보자.
AllBeanTest
package org.example.springcore.autowired;
import org.assertj.core.api.Assertions;
import org.example.springcore.AutoAppConfig;
import org.example.springcore.discount.DiscountPolicy;
import org.example.springcore.member.Grade;
import org.example.springcore.member.Member;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.*;
public class AllBeanTest {
@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);
int rateDiscountPrice = discountService.discount(member, 20000, "rateDiscountPolicy");
assertThat(rateDiscountPrice).isEqualTo(2000);
}
static 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;
}
public int discount(Member member, int price, String discountCode) {
DiscountPolicy discountPolicy = policyMap.get(discountCode);
return discountPolicy.discount(member, price);
}
}
}
discount()는 세번째 파라미터로 discountCode를 받는다. 이 파라미터가 fixDiscountPolicy냐 rateDiscountPolicy냐에 따라 할인가격을 결정하면 되는 메서드이다. 그래서 굉장히 유연하게 할인 정책을 갈아 끼울 수 있다. 이는 전략패턴과도 유사한 모습이 보인다.
결론
타입으로 조회한 빈이 2개 이상이고 모두 필요한 경우에 List, Map으로 받을 수 있다.
'Spring, Apache, Java' 카테고리의 다른 글
Bean Scope (0) | 2024.05.27 |
---|---|
Bean LifeCycle Callback (0) | 2024.05.27 |
@Autowired로 자동 주입을 할 때 빈이 2개 이상 조회된 경우 (0) | 2024.05.26 |
스프링에서 의존관계 자동 주입하는 방법들 (0) | 2024.05.25 |
@ComponentScan (0) | 2024.05.24 |