[Spring] 컨테이너에 등록된 모든 빈 조회

스프링 컨테이너에 등록한 스프링 빈들이 제대로 등록되었는지 확인해보자. 테스트 코드로 작성할 것이다. 


Test 폴더의 hello.core 아래 beanfind 패키지를 만들어주고 ApplicationContextInfoTest 클래스를 하나 만들자.

ApplicationContextInfoTest.class

package hello.core.beanfind;

import hello.core.AppConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationContextInfoTest {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("print all Bean")
    void findAllBean(){
        String[] beanDefinitionNames = ac.getBeanDefinitionNames(); //정의된 빈의 모든 이름들
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("beanDefinitionName = " + beanDefinitionName + " | object = " + bean);
        }
    }
}

.getBeanDefinitionNames() 메서드는 정의(저장)되어 있는 모든 빈들의 이름을 호출해 String 배열에 저장하는 메서드이다. 

그리고 이것들을 스프링 빈의 이름과 object를 출력해보면 다음과 같은 결과를 얻을 수 있다.

앞서 설명했듯이 위 쪽의 5개 log는 스프링이 내부적으로 스프링 자체를 확장하기 위해 사용하는 빈들이고, 아래 5개가 우리가 실제로 등록한 빈들이다. 

 

우리가 등록한 빈들만 테스트하는 코드는 다음과 같다.

...
@Test
@DisplayName("print all ApplicationBean")
void findApplicationBean(){
    String[] beanDefinitionNames = ac.getBeanDefinitionNames(); //정의된 빈의 모든 이름들
    for (String beanDefinitionName : beanDefinitionNames) {
        BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

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

.getBeanDefinition(...) 메서드는 빈에 대한 메타데이터 정보를 호출하는 메서드이다. 

BeanDefinition.ROLE_APPLICATION 은 스프링 내부에서 동작하기 위해 등록한 것이 아니라, 애플리케이션을 개발하기 위해 등록한 빈들을 반환한다. 이것이 beanDefinition.getRole()과 일치하는지 확인하면 된다. 

BeanDefinition.ROLE_APPLICATION = 직접 등록한 애플리케이션 빈
BeanDefinition.ROLE_INFRASTRUCTURE = 스프링이 내부에서 사용하는 빈

정리해보면,,,

  • 위의 첫 번째 코드(테스트 코드)를 실행하면 스프링에 등록된 모든 빈 정보를 출력할 수 있다.
  • ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회
  • ac.getBean() : 빈 이름으로 빈 객체(인스턴스)를 조회
  • 스프링이 내부에서 사용하는 빈과 직접 등록한 빈은 .getRole()구분할 수 있다.