본문 바로가기
강의 실습/스프링 핵심 원리 - 기본편

조회한 빈이 모두 필요할 때, List, Map

by jint 2026. 4. 30.

의도적으로 해당 타입 스프링 빈이 다 필요한 경우가 있다.
  ex) 클라이언트가 할인의 종류(rate, fix)를 선택

동적으로 스프링 빈을 선택해야 할 때, Map 이나 List 로 해당 타입 스프링 빈을 모두 받아서 전략패턴을 활용해 다형성을 이용하여 선택한 스프링 빈을 가져올 수 있다.
스프링에서 전략 패턴을 간단히 구현할 수 있다.

- src/test/java/hello/core/autowired/AllBeanTest.java

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.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.assertThat;

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 fixDiscountPrice = discountService.discount(member, 10000, "fixDiscountPolicy");

        assertThat(discountService).isInstanceOf(DiscountService.class);
        assertThat(fixDiscountPrice).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;

            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);
        }

    }

}


- 콘솔

policyMap = {fixDiscountPolicy=hello.core.discount.FixDiscountPolicy@5fb65013, rateDiscountPolicy=hello.core.discount.RateDiscountPolicy@38a1a26}
policies = [hello.core.discount.FixDiscountPolicy@5fb65013, hello.core.discount.RateDiscountPolicy@38a1a26]
discountCode = fixDiscountPolicy
discountPolicy = hello.core.discount.FixDiscountPolicy@5fb65013
discountCode = rateDiscountPolicy
discountPolicy = hello.core.discount.RateDiscountPolicy@38a1a26


DiscountService 는 Map 으로 모든 DiscountPolicy 를 주입받는데, fixDiscountPolicy, rateDiscountPolicy 가 주입 된다.
DiscountService 의 discount() 메서드는 discountCode 매개변수로 "fixDiscountPolicy"가 넘어오면 map 에서 fixDiscountPolicy 스프링 빈을 찾아서 실행한다.
만약 "rateDiscountPolicy"가 넘어오면 map 에서 rateDiscountPolicy 스프링 빈을 찾아서 실행한다.

· Map<String, DiscountPolicy> : key 에 스프링 빈 이름, value 에 DiscountPolicy 타입으로 조회한 모든 스프링 빈을 담는다.
만약 해당 타입 스프링 빈이 없다면 Map을 주입한다.
· List<DiscountPolicy> : DiscountPolicy 타입으로 조회한 모든 스프링 빈을 담는다.
만약 해당 타입 스프링 빈이 없다면 빈 컬렉션을 주입한다.

1) 스프링 컨테이너 생성하면서 스프링 빈 등록
스프링 컨테이너는 생성자에 클래스 정보를 받는데, 여기에 클래스 정보를 매개변수로 넘기면 해당 클래스가 스프링 빈으로 자동 등록된다.

 

new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class);


· new AnnotationConfigApplicationContext() 를 통해 스프링 컨테이너 생성
· AutoAppConfig.class, DiscountService.class 를 매개변수로 넘기면서 해당 클래스를 자동으로 스프링 빈으로 등록

-> 스프링 컨테이너를 생성하는 동시에 AutoAppConfig, DiscountService 를 스프링 빈으로 자동 등록


참고링크 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8?cid=325969

 

스프링 핵심 원리 - 기본편| 김영한 - 인프런 강의

현재 평점 5.0점 수강생 49,572명인 강의를 만나보세요. 스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다. 스프링 기본 기능, 스프

www.inflearn.com

댓글