예비개발자/SPRING

[스프링 핵심 원리- 기본편] 스프링 컨테이너에 상속 조회

삼푸요정 2023. 8. 9.
반응형
반응형
package hello.core.beanfind;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class ApplicationContextExtendsFindTest {

    AnnotationConfigApplicationContext ac = new
            AnnotationConfigApplicationContext(TestConfig.class);

    @Test
    @DisplayName("부모 타입으로 조회 시, 자식이 둘 이상 있으면 중복오류가 발생한다.")
    void findBeanByPatentTypeDuplicate()
    {
        DiscountPolicy bean = ac.getBean(DiscountPolicy.class);
    }


    @Configuration
    static class TestConfig{
        @Bean
        public DiscountPolicy rateDiscountPolicy(){
            return new RateDiscountPolicy();
        }

        @Bean
        public DiscountPolicy fixDicountPolicy(){
            return new FixDiscountPolicy();
        }
    }

}

rateDiscountPolicy와 fixDiscountPolicy 모두 DiscountPolicy를 상속 받았다.

자식이 둘 이상 존재한다면 부모타입으로 스프링 컨테이너를 조회하면 아래의 사진처럼 오류가 발생한다.

오류가 발생한 모습

 

그러므로 조회하는 코드를 아래와 같이 수정해야 한다.

    @Test
    @DisplayName("부모 타입으로 조회 시, 자식이 둘 이상 있으면 빈 이름으로 지정하면 된다.")
    void findBeanByPatentTypeBeanName()
    {
        DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy",DiscountPolicy.class);
        assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
    }

즉, DiscountPolicy로 조회를한다면 이름 부분에서 자식의 빈 이름을 지정하면 된다.

아까와 달리 정상적으로 실행된다.


    @Test
    @DisplayName("특정 하위 타입으로 조회")
    void findBeanSubtype()
    {
        RateDiscountPolicy bean = ac.getBean("rateDiscountPolicy",RateDiscountPolicy.class);
        assertThat(bean).isInstanceOf(RateDiscountPolicy.class);
    }

혹은 특정 하위 타입을 지정하여 조회 할 수 있다.

하지만 이 방법은 비추이다. 


3번째 방법은 부모 타입으로 모두 조회하는 방법이다. 

@Test
    @DisplayName("부모 타입으로 모두 조회")
    void findAllBeanByPatentType() {

        Map<String, DiscountPolicy> beanOfType = ac.getBeansOfType(DiscountPolicy.class);
        assertThat(beanOfType.size()).isEqualTo(2);
        for(String key : beanOfType.keySet()){
            System.out.println("key = "+key+"value ="+ beanOfType.get(key));
        }
    }

실행 결과

조회할 빈은 총 2개 이므로 isEqualTo() 매개변수에 2를 넣어준다. 

그리고 bean크기 만큼 for 문으로 돌려준다. 

 

그럼 2개의 빈이 출력된다. 


마지막 방법 Object로 스프링에 등로된 모든 빈을 출력하기!

    @Test
    @DisplayName("부모 타입으로 모두 조회 - Object 타입")
    void findAllBeanByObjectType() {

        Map<String, Object> beanOfType = ac.getBeansOfType(Object.class);
        for(String key : beanOfType.keySet()){
            System.out.println("key = "+key+"value ="+ beanOfType.get(key));
        }
    }

아까는 DiscountPolicy에 해당하는 2개의 자식 빈이 출력된 반면

이 코드는 스프링에 등록된 내부 빈까지 출력된다. 

그래서 아까 2개의 빈이 출력된 것 과 달리 더 많이 출력되는 모습을 볼 수 있다.

 


1) 부모타입으로 조회하되 자식의 빈 이름을 적기

2) 특정 하위 타입으로 조회(자식 타입으로 조회)

3) 부모타입으로 조회

4) Object 타입으로 조회

 

반응형

댓글