1️⃣ 개요
스프링 컨테이너에 등록된 빈을 조회하는 방법을 알아보자.
빈을 조회하는 방법엔 여러 가지가 있지만 그중에서 가장 기본이 되는 몇몇 방법을 살펴보겠다.
모든 빈을 조회하는 방법, 역할에 따른 빈을 출력하는 방법 등이 있다.
2️⃣ 모든 빈 조회
직접 등록한 스프링 빈 뿐만 아니라, 스프링 내부적으로 생성되는 빈을 모두 출력하는 방법이다.
이는 main 디렉토리가 아닌 test 디렉토리에서 확인하였다.
기본적인 코드는 다음과 같다.
public class ApplicationContextInfoTest{
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("Find All Beans")
void findAllBeans(){
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for(String beanDefinitionName : beanDefinitionNames){
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name : " + beanDefinitionName + " object : " + bean);
}
}
}
- beanDefinitionNames : String 타입을 가지는 배열이다. 'getBeanDefinitionNames()' 메소드를 통해 모든 빈 이름을 가져온다.
- 향상된 for 문 : beanDefinitionNames 배열을 순회하며 차례대로 등록된 모든 bean 이름을 가져온다.
- ac.getBean(beanDefinitionName) : 빈 이름을 통해 해당 빈을 Object 형식으로 가져온다.
- println 문 : 빈 이름과 Object 를 출력한다.
빨간 박스 내부에 있는 결과가 스프링 내부적으로 생성된 빈들이다.
박스 아래의 결과를 보면 @Bean 어노테이션을 통해 직접 등록된 빈들의 목록이 나온다.
또한 설정 파일인 AppConfig 클래스도 빈으로 등록된 것을 알 수 있다.
3️⃣ Application Bean
다음은 스프링 내부에서 사용되는 빈이 아닌, 사용자가 직접 등록하거나 외부 라이브러리와 관련된 빈을 출력하는 방법이다.
즉, 위에서 모든 빈을 출력하는 과정에서 빨간 박스를 제외한 빈들을 출력하는 방법이다.
여기서 'BeanDefinition' 이라는 개념이 등장하는데, 좀 더 자세한 설명은 아래 글을 참고하면 되겠다.
https://jnsodevelop.tistory.com/35
[Spring] Spring Container (스프링 컨테이너) - (1)
Spring Container (스프링 컨테이너) Spring 에서 'ApplicationContext' 는 '스프링 컨테이너' 라고 한다. 이는 DI, IoC 와도 관련이 있는데, 스프링 컨테이너를 통해 DI가 자동으로 되기 때문이다. 스프링 컨테이
jnsodevelop.tistory.com
1. ROLE_APPLICATION
일반적으로 사용자가 정의한 빈을 볼 수 있다.
즉, @Configuration과 @Bean으로 등록한 빈을 볼 수 있다는 것이다.
여담으로 내가 프로젝트를 진행할 때 해당 명령어를 사용하려고 했지만, 오류가 났었다.
그 이유는 ApplicationContext 를 사용했기 때문이다.
즉, BeanDefinition을 사용하기 위해선 아래 코드 처럼 AnnotationConfigApplicationContext 를 사용해야 한다.
public class ApplicationContextInfoTest{
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
/**
* 아래 코드는 BeanDefinition을 사용할 수 없다.
* ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
**/
@Test
@DisplayName("Find Application Beans")
void findAllBeans(){
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("name : " + beanDefinitionName + " object : " + bean);
}
}
}
}
결과는 아래와 같다.
2. ROLE_INFRASTRUCTURE
자주 사용되진 않지만 스프링 내부에서 사용하는 빈들을 보기 위해 사용된다.
위 코드에서 BeanDefinition.ROLE_APPLICATION 을 BeanDefinition.ROLE_INFRASTRUCTURE 로 바꿔주면 된다.
그러나 실제로 이러한 방식으로 모든 빈을 조회할 일은 많이 없을 것이다.
public class ApplicationContextInfoTest{
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
/**
* 아래 코드는 BeanDefinition을 사용할 수 없다.
* ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
**/
@Test
@DisplayName("Find Application Beans")
void findAllBeans(){
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for(String beanDefinitionName : beanDefinitionNames){
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
if(beanDefinition.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE){
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name : " + beanDefinitionName + " object : " + bean);
}
}
}
}
결과는 아래와 같다.
결과 뒤쪽에 "Creating shared instance of singleton .." 의 의미는 각 빈들이 싱글톤 객체로 관리된다는 뜻이다.
이는 스프링에서 중요한 개념 중 하나이며, 후에 @Configuration 어노테이션과 관련이 있다.
자세한 내용은 다음에 다루겠다.
참고 : 김영한-스프링 핵심 원리 (기본편)