article thumbnail image
Published 2022. 1. 14. 08:28
반응형

BeanDefinition이란?


  • 단어 그대로 스프링 빈의 설정 메타 정보이다.
  • 각 @Bean, 당 각 하나씩 메타 정보가 생성된다.
  • 스프링 컨테이너는 이 메타 정보를 기반으로 스프링 빈을 생성한다.

어떻게 다양한 설정 방식을 지원 할까?


  • 해당 글에서 빈 설정 방식을 자바 코드, xml 등 방식을 지원하는데 이게 가능한 이유가 BeanDefinition이라는 추상화가 있기 때문이다.
  • BeanDefinition은 역할(interface)가 되는 것이고, AppConfig.class, appConfig.xml, appConfig.xxx 등과 같은 것들이
    구현이 되는 것이다. 결국 스프링 컨테이너는 BeanDefinition만 바라 보기 때문에 가능한 것이다.

구조를 그림으로 보면 아래와 같다.

그림 출처 김영한의 스프링 핵심 원리 - 기본편

조금 더 상세하게 들어가 보자.

스프링 컨테이너(ApplicationContext)는 BeanDefinition만 보고 설정 방식을 지원한다고 했다.
어떤 구조로 되어 있는지 코드 레벨에서 살펴 보도록 하자.

크게 설정 정보에는 자바 설정 구현체인 AnnotationConfigApplicationContext와 xml 설정 구현체인 GenericXmlApplicationContext이 있다.

AnnotationConfigApplicationContext 코드를 보면 인스턴스 변수가 AnnotatedBeanDefinitionReader이다.
AnnotatedBeanDefinitionReader는 AppConfig.class를 읽어 BeanDefinition을 생성한다.

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

    private final AnnotatedBeanDefinitionReader reader;
....

GenericXmlApplicationContext을 코드를 보면 인스턴스 변수가 XmlBeanDefinitionReader이다.
XmlBeanDefinitionReader도 동일하게 appConfig.xml을 읽어 BeanDefinition을 생성하게 된다.

public class GenericXmlApplicationContext extends GenericApplicationContext {

    private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
...

그림 출처 김영한의 스프링 핵심 원리 - 기본편

BeanDefinition 메타 정보 로그 확인


실제로 BeanDefinition의 메타 정보가 어떻게 되어있는지 대략적으로만 보도록 하자.

아래와 같이 메타 정보를 확인 할 수 있다.

class BeanDefinitionTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @DisplayName("빈 설정 메타정보 확인")
    @Test
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                System.out.println("beanDefinitionName = " + beanDefinitionName);
                System.out.println("beanDefinition = " + beanDefinition);
            }
        }
}

아래에 자바 코드로 등록한 빈의 메타 정보를 확인 해보도록 하겠다.

@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

로그는 이처럼 나오는데 이런게 있다는 정도만 알면 된다. 딱 2개만 살펴보자.
factoryBeanName → AppConfig의 명이 되고, factoryMethodName → 빈의 명이 된다.
BeanDefinition은 이런 식으로 여러 메타 정보를 가진다.

beanDefinitionName = memberService
beanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false;
                               factoryBeanName=appConfig; factoryMethodName=memberService; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfig

beanDefinitionName = memberRepository
beanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; 
                             factoryBeanName=appConfig; factoryMethodName=memberRepository; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfig

정리


  • 스프링은 다양한 설정 정보를 지원하는데 BeanDefinition이라는 빈의 메타 정보를 추상화하는 것으로 가능하게 한다.
반응형
복사했습니다!