JAVA/Spring

[Spring] 스프링 빈 조회하기

JongHyun99 2021. 7. 9. 13:39
728x90

모든 Bean 출력하기

 

메소드

getBeanDefinitionNames() // 스프링의 모든 빈 이름으로 조회
ac.getBean(빈 이름 입력) // 빈 이름으로 빈 객체(인스턴스) 조회

 

 

코드

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    String[] beanDefinitionNames = ac.getBeanDefinitionNames();

    for (String beanDefinitionName : beanDefinitionNames) {
        Object bean = ac.getBean(beanDefinitionName);
        System.out.println("name = " + beanDefinitionName + " object = " + bean);
    }
}

 

출력값

name = org.springframework.context.annotation.internalConfigurationAnnotationProcessor object = org.springframework.context.annotation.ConfigurationClassPostProcessor@71a8adcf
name = org.springframework.context.annotation.internalAutowiredAnnotationProcessor object = org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@27462a88
name = org.springframework.context.annotation.internalCommonAnnotationProcessor object = org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@82de64a
name = org.springframework.context.event.internalEventListenerProcessor object = org.springframework.context.event.EventListenerMethodProcessor@659499f1
name = org.springframework.context.event.internalEventListenerFactory object = org.springframework.context.event.DefaultEventListenerFactory@51e69659
name = appConfig object = hello.core.AppConfig$$EnhancerBySpringCGLIB$$564c7a08@47e2e487
name = memberService object = hello.core.member.MemberServiceImpl@201a4587
name = memberRepository object = hello.core.member.MemoryMemberRepository@61001b64
name = orderService object = hello.core.order.OrderServiceImpl@4310d43
name = discountPolicy object = hello.core.discount.RateDiscountPolicy@54a7079e

 

설명

getBeanDefinitionsNames의 값들을 배열 변수에 넣고 for문으로 getBean에 하나씩 대입한다.

 

 


 

 

직접 생성한 Bean만 출력하려면?

위 출력값은 직접 설정한 Bean 외 Spring에서 자동으로 등록하는 Bean도 함께 출력되고 있다.

본인이 직접 설정한 Bean만 출력하기 위해선 아래와 같이 사용한다.

 

코드

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    String[] beanDefinitionNames = ac.getBeanDefinitionNames();

    for (String beanDefinitionName : beanDefinitionNames) {

                    BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

                    if (beanDefinition.getRoel() == BeanDefinition.ROLE_APPLICATION) {
                    Object bean = ac.getBean(beanDefinitionName);
                    System.out.println("name = " + beanDefinitionName + " object = " + bean);
                        }
            }
        }

 

설명

BeanDefinition : Bean에 대한 메타데이터 정보를 다루는 클래스
Role ROLE_APPLICATION : 직접 등록한 애플리케이션 빈
Role ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈

BeanDefinition 클래스로 생성한 변수에 getBeanDefinition메소드의 인자값으로 Bean의 이름을 넣어은 값을 대입하여 Bean의 정보를 담는다.

그 다음 조건문을 이용하여 bean의 정보가 직접 만든 값일 때만 출력하게 한다.

 


 

단일 Bean 조회

모든 Bean이 아닌 특정 Bean을 확인하고 싶을 때 방법이다.

 

메소드

ac.getBean("memberService", MemberServiceImpl.class) // getBean(빈이름, 타입)
ac.getBean("memberService") // getBean(빈이름)
ac.getBean(MemberServiceImpl.class) // getBean(타입)

이름으로 검색, 타입으로 검색, 둘다 사용한 검색 모두 쓸 수 있다.

 

코드

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
            System.out.println(ac.getBean("memberService", MemberServiceImpl.class));
      System.out.println(ac.getBean("memberService"));
      System.out.println(ac.getBean(MemberServiceImpl.class));

 

출력

hello.core.member.MemberServiceImpl@5386659f
hello.core.member.MemberServiceImpl@5386659f
hello.core.member.MemberServiceImpl@5386659f

 

조회에 이름을 쓰거나 타입을 쓰거나 이름, 타입 둘다 사용해도 똑같은 결과가 나온다.

 

만약 조회할 스프링 빈이 없다면?

NoSuchBeanDefinitionException: No bean named 'xxxxx' available // 에러 발생

NoSuchBeanDefinitionException 에러가 발생한다.

 


 

특정 타입의 빈을 모두 조회하기

 

메소드

getBeansOfType(조회할 클래스);

 

 

코드

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SameBeanConfig.class);

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

 

 

출력

Creating shared instance of singleton bean 'memberRepository1'
Creating shared instance of singleton bean 'memberRepository2'

 

 

설명

Bean 설정파일을 getBeansOfType으로 호출하면 인자값으로 받은 클래스를 모두 리턴해준다.

리턴 타입은 Map이고 제네릭은 <String, Type>이 된다.

iterator 등 반복문 출력 로직으로 조회할 수 있다.

 


 

상속관계의 빈 조회

상속관계의 빈들은 부모타입을 조회하면 자식타입도 모두 조회된다.

최고 부모인 Object 타입으로 조회하면 모든 스프링 Bean을 조회한다.

공부한 출처 : 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/lecture/55356?tab=curriculum