공부노트/Java

Spring Bean의 조회, 등록 그리고 구조

사당동씩씩이 2025. 3. 23. 22:52
320x100

이영한 님의 스프링 핵심원리 - 기본편을 들으며 필기한 것이다.

 

스프링에 등록된 빈을 조회하는 방법을 정리해두려 한다.

자주 사용하지 않을 것같아서 막상 필요할 때 찾아보기 위한 요약본이다.

 

1. Bean 조회 

import 는 생략한다.

public class ApplicationContextBeanFindTest {
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
    
    @Test
    @DisplayName("이름으로 조회할 수 있다.")
    void findBeanByName() {
    	MemberService memberService = ac.getBean("memberService", MemberService.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }
    
    @Test
    @DisplayName("이름없이 타입으로 조회할 수 있다.")
    void findBeanByName() {
    	MemberService memberService = ac.getBean(MemberService.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }
    
    @Test
    @DisplayName("구체 타입으로 조회")
    void findBeanByName2() {
        MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }
    
    @Test
    @DisplayName("부모 타입으로 조회시 자식이 두개 이상인경우 예외가 발생한다.")
    void findBeanByName() {
    	assertThrows(NoUniqueBeanDefinitionException.class,
                () -> ac.getBean(DiscountPolicy.class));
    }
    
    @Test
    @DisplayName("부모 타입으로 모두 조회하기 - Object")
    void findBeanByObjectType() {
        Map<String, Object> beansOfType = ac.getBeansOfType(Object.class);
    }
    
    //정의된 빈 전체 호출
    @Test
    @DisplayName("모든 bean 출력하기")
    void findAllBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name =  " + beanDefinitionName + "object = " + bean);
        }
    }

    @Test
    @DisplayName("application bean 출력하기")
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            //Role ROLE_APPLICATION : 직접 등록한 애플리케이션 빈
            //Role ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈
            if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                Object bean = ac.getBean(beanDefinitionName);
                System.out.println("name =  " + beanDefinitionName + "object = " + bean);
            }
        }
    }
    
}

 

Memo

  • 스프링 빈은 등록된 "이름"과 "타입"으로 호출할 수 있다.
  • 스프링 빈 등록시 이름의 기본값 : 등록한 Configuration 클래스의 매서드명은 빈 이름이 된다.
  • @Bean("name2") 형식으로 이름을 직접 지정 할 수 있다.
  • 타입으로 호출하는 경우 하위자식들이 모두 호출됨으로 주의해야 한다.
  • 예시로 Object.class로 호출하면 모든 스프링 빈이 호출된다.
  • 당연하지만 타입호출시 2개 이상이 호출되면 빈 이름 또는 구현채를 명시해서 불러올 수 있다.

Method

  • getBeanDefinitionNames() : 모든 빈 이름을 조회한다.
  • getBean() : 빈 이름, 타입을 사용해서 객체(인스턴스)를 조회한다.
  • getRole() : 사용자가 정의한 빈과 스프링 내부 빈을 구분해볼 수 있다. (코드예시 최하단)
  • getBeansOfType() : 특정 타입의 모든 빈을 조회

2. ApplicationContext 의 구조

ApllicationContext 의 상속 정보

<<interface>>ApplicationContext 는<<interface>>BeanFactory을 기능을 모두 상속받으며 getBean은 BeanFactory의 기능이다. 이외 다른 부가기능을 포함하고 있기 때문에 ApplicationContext를 주로 사용한다.

 

EnvironmentCapable : 애플리케이션 환경(Enviroment) 관련 정보 제공

ListableBeanFactory : 등록된 모든 빈을 조회할 수 있는 기능 제공

HierarchicalBeanFactory : 부모-자식 구조의 빈 팩토리 지원

MessageSource : 국제화(i18n) 메세지 처리 지원, 예를 들면 한국에서 들어오면 한국어로 출력

ApplicationEventPublisher : 애플리케이션 이벤트 발행 및 관리

ResoucePatternResolver : 패턴을 사용한 리소스 검색 기능 제공

 

- BeanFactory, ApplicationContext를 스프링 컨테이너라고 한다.

 

3. BeanDefinition - 스프링 빈 설정 메타 정보

스프링 빈을 등록하는 방법

 

xml을 이용하여 직접 등록 

GenericXmlApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");

 

appconfig.class 팩토리메서드/팩토리빈을 통해 등록

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

 

위 코드에서 ApplicationContext로 받은 이유는 "getDefinitionNames()"를 사용하기 위해서다.

 

https://spring.io/projects/spring-framework

 

Spring Framework

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform. A key element of Spring is infrastructural support at the application level: Spring focuse

spring.io

 

출처 : inflearn 이영한님의 스프링 핵심원리 - 기본편

 

스프링 컨테이너는 BeanDefinition을 통해서 메타정보를 읽어온다. 각 설정방법에 따라 다른 Reader를 사용할 수 있으며 사용자가 직접 리더를 만들어서 새로운 등록 양식을 만들어 사용할수 있다.

728x90