[기본기] 6-2. 빈 중복 조회, 빈 상속 관계

khyojun·2022년 9월 26일
0

본 게시글은 김영한님의 스프링 핵심 원리 기본편을 정리한 글입니다.


📌스프링 빈 조회 - 동일 타입이 둘 이상일 경우

그럼 어떻게 하면 될까? 이미 답은 나왔다. 빈 조회할때의 여러가지 방법이 있다고 하였는데 그럼 그냥 타입이 2개 이상이면 bean 이름으로 찾으면 된다. 그러니까 결국 bean 이름도 함께 지정하면서 조회를 해주면 된다.

그런데 이게 타입이 2개인지 아닌지를 아는데 있어서 지금 우리가 작성할 예시코드들은 실제로 Bean등록을 그렇게 많이 하지는 않는데 이것도 예전에 말했던 예시들처럼 몇 백개가 될 거면 그럼 동일 타입이 2개인지 흠... 확인을 우째 해야할까...
방법이 있는데 .getBeansOfType() 을 통하여서 해당 타입의 모든 빈들을 조회를 할 수가 있다. 그렇게 테스트 코드들 돌리면서 한 번 알아봐도 되고 찾아보면 될 거 같다.

📂 ApplicationContextSameBeanFindTest

public class ApplicationContextSameBeanFindTest {

    AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(FindSameBean.class);

    @Test
    @DisplayName("타입으로 조회시 같은 타입이 둘 이상 있으면, 중복 오류 발생")
    void findBeanbyNameError(){
       // MemberRepository memberRepository = ac.getBean(MemberRepository.class);
        Assertions.assertThrows(NoUniqueBeanDefinitionException.class, () -> ac.getBean(MemberRepository.class));
    }

    @Test
    @DisplayName("타입으로 조회 시 같은 타입이 둘 이상이 잇을 경우 타입또 적고 이름도 같이 적어준다.")
    void findBeanbyName(){
        MemberRepository memberRepository = ac.getBean("memberRepository1",MemberRepository.class);
        assertThat(memberRepository).isInstanceOf(MemberRepository.class);
    }

    @Test
    @DisplayName("특정 타입을 모두 조회하기.")
    void findBeansOfType(){
        Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key));
        }
        System.out.println("beansOfType = " + beansOfType);
        assertThat(beansOfType.size()).isEqualTo(2);
    }

    @Configuration
    static class FindSameBean{

        @Bean
        public MemberRepository memberRepository1(){
            return new MemoryMemberRepository();
        }

        @Bean
        public MemberRepository memberRepository2(){
            return new MemoryMemberRepository();
        }
    }
}

맨 아래의 코드를 보게 되면 특정 타입을 모두 조회를 하게 되는데 여기서 나중에 맨 밑에 있는 beansOfType에 대한 출력물을 보게 되면 key 값으로는 해당 빈의 이름 그리고 value 값으로 각 bean의 참조값들을 꺼내온다.

📌스프링 빈 조회 - 상속 관계

스프링 빈을 조회하는 방법 중 또 하나의 방법에는 상속 관계를 활용하는 방안도 있다고 한다. 여기서 알고 갈 것이 있는게 부모 타입을 조회하면, 그 자식 타입도 함께 조회한다라는 특성도 있다. 그리고 모든 자바객체의 최고 부모인 Object타입으로 조회를 하면 즉 몯느 스프링 빈을 조회도 된다고 볼 수 있다.

다음 그림처럼 해당 번호를 부르면 밑에 있는 자식들까지 다 조회한다는 것을 볼 수 있다.

📂 ApplicationContextExtendsFindTest

public class ApplicationContextExtendsFindTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);

    @Test
    @DisplayName("부모 타입으로 조회시, 자식이 둘 이상이 있으면, 중복 오류가 발생한다.")
    void findBeanByParentType(){
        //DiscountPolicy discountPolicy = ac.getBean(DiscountPolicy.class);
        Assertions.assertThrows(NoUniqueBeanDefinitionException.class, () -> ac.getBean(DiscountPolicy.class));

    }

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

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

    @Test
    @DisplayName("부모 타입으로 모두 조회하기")
    void findAllBeanByParentType(){
        Map<String, DiscountPolicy> discountPolicyMap = ac.getBeansOfType(DiscountPolicy.class);
        assertThat(discountPolicyMap.size()).isEqualTo(2);
        for (String key : discountPolicyMap.keySet()) {
            System.out.println("key = " + key + " value = " + discountPolicyMap.get(key));
        }
    }

    @Test
    @DisplayName("부모 타입으로 모두 조회하기 - Object")
    void findAllBeanByObject(){
        Map<String, Object> beansOfType = ac.getBeansOfType(Object.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key));
        }

    }

    @Configuration
    static class TestConfig{

        @Bean
        public DiscountPolicy ratediscountPolicy(){
            return new RateDiscountPolicy();
        }

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

🖼 부모타입

🖼 부모타입 - Object

오.... 상당히 많다는 것을 알 수 있었던 거 같다. 참고로 아래 스크롤을 한참 내려도 계속 출력이 되고 있었다.

출처

  1. 김영한님의 스프링 핵심 원리 기본편(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)
profile
코드를 씹고 뜯고 맛보고 즐기는 것을 지향하는 개발자가 되고 싶습니다

0개의 댓글