본문 바로가기

Spring/Spring

(SPRING) Spring ApplicationContext의 내부 (1)

요즘 스프링의 ApplicationContext의 빈 생성 원리에 대해서 2주 동안 지속적으로 살펴보았다. 어려워서 2주간의 시간이 걸린 것이 아니라 감탄 + 복잡하게 얽혀있는 인터페이스 추상클래스 클래스 와의 관계 때문에 시간이 조금 걸렸다.(아직도 하고 있다..;)
일단 시작한 계기는 Bean을 등록하면 분명 new를 사용해서 객체를 생성할텐대..  그 부분을 찾고 싶었다.

아직 완벽하지는 않지만 느낀 바는 두 가지이다.
스프링은 신기하게도 인스턴스를 등록하는 것이 아니라 registry로 Bean에 대한 정보를 저장한다. 
또 다른 느낀 점은 스프링이 객체지향적으로 잘 설계돼있다는 점이었다.
객체지향에 대한 막연한 개념이 실제 사용되는 코드를 보면서 아 이렇게 사용하면 되는구나 라고 개념이 명확해졌다.
자 처음부터 차근차근히 살펴보도록 하겠다.

살펴볼 코드는 아래와 같이 단순하다.  AnnotationConfigApplicationContext는 스프링을 xml에서 어노테이션의 시대를 열게 해 준 고마운 클래스이다.

ApplicationContext context = new
        AnnotationConfigApplicationContext(BookFactory.class);

AnnotationConfigApplicationContext 인스턴스를 생성하면 부모의 인스턴스도 함께 생성한다. 부모의 인스턴스는 아래와 같다.

이때 GenericApplicationContext 인스턴스 생성 시 DefaultListableBeanFactory의 인스턴스도 생성된다.


AnnotatedBeanDefinitionReader

이제 다시 AnnotationConfigApplicationContext로 돌아와서 해당 디폴트 생성자에는

  • AnnotatedBeanDefinitionReader
  • ClassPathBeanDefinitionScanner

해당 두 가지의 인스턴스 틀 생성한다. 이때 아규먼트는 자기 사신 (this)이다.

이때 registry는 BeanDefinitionRegistry 인터페이스의 타입으로 받는다. 왜냐면 AnnotationConfigApplicationContext는 BeanDefinitionRegistry의 구현체 이기 때문에 다형성의 특징으로 받을 수 있다.


public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

이제 reader에 정보를 본격적으로 등록한다.

여기서 environment는 환경정보를 뜻하는데 StandardEnvironment를 가져온다. 

ConditionEvaluator는 해당 클래스 내부에 ConditionContextImpl 내부 static 클래스의 정보를 가지고 있다.

private final ConditionContextImpl context;

ConditionContextImpl의 정보가 외부에서 수정하지 못하도록 내부 static 클래스로 만들어서 정보를 해당 클래스의 외부 클래스에서만 접근이 가능하게끔 설계하였다.

beanFactory에 대한 정보를 저장할 때 이전에 GenericApplicationContext 저장했던 DefaultListableBeanFactor 인스턴스를 저장한다.


AnnotationConfigUtils

AnnotationConfigUtils 클래스는 어노테이션 기반 설정에 정의되어있는 공통되는 BeanPostProcessor, BeanFactoryPostProcessor의 편리한 등록을 도와주는 유틸리티 클래스이다.

Utility class that allows for convenient registration of common BeanPostProcessor and BeanFactoryPostProcessor definitions for annotation-based configuration. Also registers a common AutowireCandidateResolver.

registerAnnotationConfigProcessors 메서드에서 모든 과정이 진행된다.

dependencyComparator로 AnnotationAwareOrderComparator

autowireCandidateResolver로 ContextAnnotationAutowireCandidateResolver가 등록된다.

 

그리고 LinkedHashSet 컬렉션으로 아래와 같은 빈에 대한 정의를 정의한다.

public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalConfigurationAnn otationProcessor";

public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalAutowiredAnnotat ionProcessor";

public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalCommonAnnotation Processor";

public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME =
"org.springframework.context.event.internalEventListenerProcessor";

public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
"org.springframework.context.event.internalEventListenerFactory";