[spring] 스프링 빈 조회하기

괭이밥·2022년 11월 5일

spring

목록 보기
4/10
post-thumbnail

🔎 목차

  1. 이름으로 조회
  2. 타입으로 조회
  3. 스프링 빈 모두 조회
  4. 특정 타입 스프링 빈 모두 조회하여 사용하기

들어가기 앞서 사용한 스프링 컨테이너 구현체는 AnnotationConfigApplicationContext이다.
예제로 나온 acApplicationContext ac = new AnnotationConfigApplicationContext 이다.


🍃 이름으로 조회

  • ac.getBean("빈이름") : 빈이름에 해당되는 인스턴스 조회
  • ac.getBean("빈이름", 클래스명.calss) : 타입까지 지정, 반환타입 결정

예제

    @Test
    void findBeanByName(){
        Object bean = ac.getBean("myBean");
        //MyBean bean = ac.getBean("myBean", MyBean.class); - 타입까지 지정
        
        System.out.println("bean = " + bean);
        Assertions.assertThat(bean).isInstanceOf(RedMyBean.class);
    }


🍃 타입으로 조회

타입으로 스프링 빈 조회

  • ac.getBean(클래스명.calss) : 해당 타입의 인스턴스 조회

예제

    @Test
    void findBeanByType(){
        //스프링 컨테이너에 해당 타입 1개만 있으면 타입으로만 조회 가능
        MyRepository bean1 = ac.getBean(MyRepository.class);
        System.out.println("bean = " + bean1);
        Assertions.assertThat(bean1).isInstanceOf(MemoryMyRepository.class);
    }

같은 타입이 2개 이상인 경우

  • NoUniqueBeanDefinitionException 예외 발생
  • 해결 방법
    1. 구현체 클래스 단위로 구체적으로 조회
    2. 이름과 함께 조회 - 위와 동일

예제 - 구현체 클래스 단위로 조회해보기

   @Test
    void findBeanByType(){
        //같은 타입이 2개 이상 있는 경우 이름 지정
        MyBean bean2 = ac.getBean("myBean", MyBean.class);
        System.out.println("bean2 = " + bean2);
        Assertions.assertThat(bean2).isInstanceOf(RedMyBean.class);
    }


🍃 스프링 빈 모두 조회

스프링 빈 모두 출력해보기

  • ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름 조회
  • ac.getBean("빈이름") : 빈 이름으로 빈 인스턴스 조회

예제

	@Test
    void findAllBean(){
        String[] names = ac.getBeanDefinitionNames();
        for (String name : names) {
            Object bean = ac.getBean(name);
            System.out.println("bean = " + bean);
        }
    }

실행 결과

  • 스프링 내부에서 사용하는 기본 빈 5개 같이 출력
  • 설정 정보 클래스도 빈으로 등록되어 출력
bean = org.springframework.context.annotation.ConfigurationClassPostProcessor@2d778add
bean = org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@73302995
bean = org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@1838ccb8
bean = org.springframework.context.event.EventListenerMethodProcessor@6c2ed0cd
bean = org.springframework.context.event.DefaultEventListenerFactory@7d9e8ef7
bean = test.core.AppConfig$$EnhancerBySpringCGLIB$$a8475dc7@f107c50
bean = test.core.bean.RedMyBean@51133c06
bean = test.core.reopsitory.MemoryMyRepository@4b213651
bean = test.core.bean.GreenMyBean@4241e0f4

내가 등록한 스프링 빈만 조회

  • ac.getBeanDefinition("빈 이름") : 빈의 메타 정보 불러옴
    • ac의 타입이 AnnotationConfigApplicationContext 어야 함
    • AnnotationConfigApplicationContext ac = new ...
  • getRole() : 빈의 종류 구별
    • ROLE_APPLICATION : 내가 등록한 빈
    • ROLE_INFRASTRUCTURE : 스프링 배부에서 사용하는 빈

예제

    @Test
    void findAllMyBean(){
        String[] names = ac.getBeanDefinitionNames();
        for (String name : names) {
            BeanDefinition beanDefinition = ac.getBeanDefinition(name);
            if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION){
                Object bean = ac.getBean(name);
                System.out.println("bean = " + bean);
            }
        }
    }

실행 결과

bean = test.core.AppConfig$$EnhancerBySpringCGLIB$$a8475dc7@2d778add
bean = test.core.bean.RedMyBean@73302995
bean = test.core.reopsitory.MemoryMyRepository@1838ccb8
bean = test.core.bean.GreenMyBean@6c2ed0cd


🍃 특정 타입 스프링 빈 모두 조회하여 사용하기

특정 타입의 스프링 빈을 모두 조회하고 사용하고 싶을 때 Map, List를 사용하면 된다.

  • Map
    • Map<string, 특정타입> 으로 받아온다.
    • string은 스프링 빈의 이름이며 스프링 컨테이너에 등록된 빈이다.
  • List
    • List<특정타입>으로 받아온다.
    • list에는 스프링 빈에 등록된 인스턴스들이 들어있다.

예제 - 특정 타입 모두 가져오는 클래스

  • AllBean 클래스
    • MyBean 타입을 모두 조회하고 사용한다.
    • @Component로 스프링 빈에 등록
    • whatBean 메서드
      • bean 이름 파라미터 넘김
      • 받은 bean 이름으로 Map에서 조회 후 클래스 출력
  • MyBean 인터페이스 구현체
    • GreenMyBean: @Component로 스프링 빈에 등록
    • RedMyBean: @Component로 스프링 빈에 등록
  • MyBean을 모두 가져오기
    • BeanMap: Map으로 가져옴
    • BeanList: List로 가져옴
@Component
public class AllBean {
    private final Map<String, MyBean> beanMap;
    private final List<MyBean> beanList;

    @Autowired
    public AllBean(Map<String, MyBean> beanMap, List<MyBean> beanList) {
        this.beanMap = beanMap;
        this.beanList = beanList;
    }

    public void whatBean(String bean){
        MyBean myBean = beanMap.get(bean);
        System.out.println("myBean.getClass() = " + myBean.getClass());
    }
}

테스트 코드 작성

  • AnnotationConfigApplicationContext으로 스프링 컨테이너 접근
  • AppConfig 클래스
    • @ComponentScan 붙은 설정 정보 클래스
  • AllBean조회 후 whatBean 메서드 호출
    • 파라미터로 GreenMyBean, RedMyBean 호출해보기
 @Test
 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
void AllBeanTest(){
    AllBean bean = ac.getBean(AllBean.class);

    bean.whatBean("greenMyBean");
    bean.whatBean("redMyBean");
    }

실행결과

myBean.getClass() = class test.core.bean.GreenMyBean
myBean.getClass() = class test.core.bean.RedMyBean


출처
인프런 '스프링 핵심 원리 - 기본편' 강의

profile
개발도 하고 싶은 클라우드 엔지니어

0개의 댓글