Spring에서 스프링 빈 관리

hoyong.eom·2023년 7월 1일
0

스프링

목록 보기
3/59
post-thumbnail

Spring

스프링 빈 관리 방법

스프링빈은 스프링에서 자체적으로 등록해주는 빈들도 있고, 개발자가 다형성을 이용해서 동일한 타입의 여러 구체 클래스를 스프링빈으로 등록해서 사용할 수 있다.

다음과 같은 상황이 있다고 가정해보자.

OrderRepository 라는 인터페이스가 존재한다.
OrderRepository를 상속받아 각각 다른 방식으로 구현한 OrderRepositoryImpl1, OrderRepositoryImpl2가 존재한다.

개발자는 OrderRepositoryImpl1, OrderRepositoryImpl2를 스프링빈으로 등록해서 사용한다.(스프링 버전에 따라서 동일한 타입이 등록되지 않을 수 있다. 추가 설정이 필요할 수 있음.)

다형성을 활용해서 개발자는 OrderRepository 타입의 스프링빈을 사용한다.

하지만, OrderRepository 타입의 스프링빈은 2가지가 등록 되어 있다. 스프링 입장에서는 어떤 스프링빈을 가져와서 사용해야할지 몰라 에러를 내뱉는다.

이러한 상황에서 어떻게 처리해야할까?

1. @Primary

@Primary은 스프링빈으로 등록될 구체 클래스에 지정해줄 수 있다.
즉, 동일한 타입의 스프링빈이 여러개 등록되어 있을때, 의존관계 주입시, @Primary가 지정된 스프링빈을 주입받아 사용한다.

2. @Qualifier

@Qualifier는 타입 이외의 추가 구분자라고 한다. 즉, 동일한 타입의 스프링빈이 여러개 일때, 타입이 동일하면 @Qualifier를 이용해서 추가로 구분해서 의존관계주입을 한다.

간단한 사용 예시는 아래와 같다.

@Component
@Qualifier(value = "mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy

-------

public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
	this.memberRepository = memberRepository;
	this.discountPolicy = discountPolicy;
}

3. Autowired 매칭

@Autowired를 이용해서 의존관계자동주입을 하게 되면 아래와 같은 규칙을 따른다.

일반적으로는 타입을 통해서 스프링빈을 조회하고 등록된 스프링빈이 여러개인경우, 필드 이름 또는 파라미터 이름으로 확인한다.

4. 모든 스프링 빈 조회

스프링빈은 Map, List 으로 조회도 가능하다.
아래의 코드는 동일한 타입으로 등록된 모든 스프링빈을 조회한다.

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

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

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

DiscountService를 스프링 빈으로 등록하면 @Autowired가 생략되었지만(생성자가 1개인 경우 생략 가능)
의존관계자동주입에 의해서 생성자를 통해서 의존관계가 자동 주입된다. 이때, DiscountPolicy 인터페이스 타입으로 등록된 모든 스프링빈이 주입된다.

policyMap = {fixDiscountPolicy=hello.core.discount.FixDiscountPolicy@14d14731, rateDiscountPolicy=hello.core.discount.RateDiscountPolicy@2eced48b}
policyList = [hello.core.discount.FixDiscountPolicy@14d14731, hello.core.discount.RateDiscountPolicy@2eced48b]

이제 모든 스프링빈이 조회된 Map이나 List에서 가져와 아래처럼 사용할 수 있다.

DiscountPolicy discountPolicy = policyMap.get(discountCode);
System.out.println("discountCode = " + discountCode);
System.out.println("discountPolicy = " + discountPolicy);
return discountPolicy.discount(member, price);

참고

해당 포스팅은 아래의 강의를 공부 후 개인적으로 정리한 내용입니다.
김영한님의 스프링 기본편

0개의 댓글