본문 바로가기
[inflearn] 스프링 핵심 원리 - 기본편/섹션 4 - 스프링 컨테이너와 스프링 빈

4-2. 모든 빈 조회, 어플리케이션 빈 조회

by 슬픈 야옹이 2023. 11. 7.

 

스프링 컨테이너에 빈이 잘 등록되었는지 조회해서 확인할 수 있다.

 

 

 

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

 

테스트 폴더에 beanfind 패키지를 하나 생성하고, ApplicationContextInfo 테스트 클래스를 생성한다.

beanfind.ApplicationContextInfoTest 클래스 생성

 

 

AnnotationConfigApplicationContext 컨테이너를 생성하고, 모든 빈을 조회하는 테스트 메서드를 작성한다.

 

ApplicationContextInfoTest.java

 

+) JUnit5부터 테스트 클래스에 public을 붙일 필요가 없어졌다.

 

ApplicationContextInfoTest.java

package hdxian.hdxianspringcore.beanfind;

import hdxian.hdxianspringcore.AppConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

class ApplicationContextInfoTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("모든 빈 출력하기")
    void findAllBean() {
        // 등록된 모든 빈의 이름을 배열로 리턴.
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            // 빈 이름이 key, 빈(객체)이 value
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name = " + beanDefinitionName + ", object = " + bean);
        }
    }

}

 

findAllBean() 메서드는 스프링 컨테이너에 등록된 모든 빈을 조회한다.

 

getBeanDefinitionNames()

getBeanDefinitionNames()는 등록된 모든 스프링 빈의 이름들을 String[] 타입으로 가져온다.

 

빈 이름은 스프링 빈의 key이므로 빈 이름으로 모든 스프링 빈을 조회할 수 있다.

 

getBean()

모든 스프링 빈 이름에 대해 getBean()으로 빈을 꺼내오고, 빈의 정보를 출력한다.

 

 

테스트 결과로 스프링 컨테이너에 등록된 모든 빈의 이름과 객체 정보가 출력된다.

실행 결과 (findAllBean)

 

테스트 결과를 보면, memberRepository 등 직접 등록한 빈 말고도 org.springframework... 등으로 시작하는 빈이 몇 개 보인다.

 

이러한 빈들은 스프링이 자체적으로 생성해 사용하는 빈으로, 컨테이너를 생성할 때 자동으로 등록된다.

 

 

 

 

어플리케이션 빈 조회

모든 스프링 빈 말고, 우리가 직접 등록한 빈만 확인해보자.

 

다음과 같은 테스트 메서드를 추가한다.

어플리케이션 빈 조회 (findApplicationBean())

 

findApplicationBean()

@Test
@DisplayName("어플리케이션 빈 출력하기")
void findApplicationBean() {
    String[] beanDefinitionNames = ac.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        // 전달한 이름에 해당하는 빈의 Definition(메타데이터)를 가져옴.
        BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

        // 각 빈의 Definition에는 enum 형태의 Role이 정의되어 있다.
        // Role ROLE_APPLICATION: 직접 등록한 어플리케이션 빈
        // Role ROLE_INFRASTRUCTURE: 스프링이 내부적으로 생성해 사용하는 빈

        // ROLE이 ROLE_APPLICATION인 빈들만 출력하면 내가 만든 빈들만 출력해서 확인할 수 있다.
        if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name = " + beanDefinitionName + ", object = " + bean);
        }

    } // end of for(beanDefinitionName:Names)
}

 

findApplicationBean()은 개발자가 직접 등록한 빈을 조회한다.

 

getBeanDefinition(beanDefinitionName)

getBeanDefinitionNames()로 모든 스프링 빈 이름을 가져온 후,

빈 이름을 바탕으로 해당 빈의 BeanDefinition(메타데이터)를 가져온다.

 

 

getRole()

BeanDefinition에는 enum 타입의 Role 속성이 존재한다.

Role에는 ROLE_APPLICATION과 ROLE_INFRASTRUCTURE, ROLE_SUPPORT가 존재한다.

BeanDefinition.Role

  • ROLE_APPLICATION
    • 외부 라이브러리 등 개발에 사용되는 빈.
    • 사용자가 정의해 등록한 빈이 여기에 해당한다.
  • ROLE_INFRASTRUCTURE
    • 스프링이 내부에서 사용하는 빈.
  • ROLE_SUPPORT
    • 모르겠다. 아직 배우지 않았다.

 

Role이 ROLE_APPLICATION인 빈들을 출력하면 어플리케이션 빈, 즉 직접 등록한 빈만 조회할 수 있다.

실행 결과 (findApplicationBean)

 

 

 

전체 코드 (ApplicationContextInfoTest.java)

package hdxian.hdxianspringcore.beanfind;

import hdxian.hdxianspringcore.AppConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

class ApplicationContextInfoTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("모든 빈 출력하기")
    void findAllBean() {
        // 등록된 모든 빈의 이름을 배열로 리턴.
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            // 빈 이름이 key, 빈(객체)이 value
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name = " + beanDefinitionName + ", object = " + bean);
        }
    }

    @Test
    @DisplayName("어플리케이션 빈 출력하기")
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            // 전달한 이름에 해당하는 빈의 Definition(메타데이터)를 가져옴.
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            // 각 빈의 Definition에는 enum 형태의 Role이 정의되어 있다.
            // Role ROLE_APPLICATION: 직접 등록한 어플리케이션 빈
            // Role ROLE_INFRASTRUCTURE: 스프링이 내부적으로 생성해 사용하는 빈

            // ROLE이 ROLE_APPLICATION인 빈들만 출력하면 내가 만든 빈들만 출력해서 확인할 수 있다.
            if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                Object bean = ac.getBean(beanDefinitionName);
                System.out.println("name = " + beanDefinitionName + ", object = " + bean);
            }


        } // end of for(beanDefinitionName:Names)
    }


}

 

 

 

정리하자면,

 

모든 빈 출력하기

  • getDefinitionNames()로 빈 이름들을 받아온다.
  • getBean(beanName)으로 모두 호출해 정보를 출력한다.

 

어플리케이션 빈 출력하기

  • getDefinitionNames()로 빈 이름들을 받아온다.
  • getBeanDefinition(beanName)으로 빈들의 BeanDefinition(메타데이터)를 가져온다.
  • BeanDefinition 객체의 getRole()을 호출해 리턴값이 ROLE_APPLICATION이면 정보를 출력한다.