(SPRING) Spring ApplicationContext의 내부 (2)

(SPRING) Spring ApplicationContext의 내부 (2)

https://jwdeveloper.tistory.com/189

이때까지 살펴보았던 과정은 인스턴스를 생성하거나 초기화하는 과정이었다.

이제 실질적으로 Bean을 등록하는 과정을 살펴보자

Bean을 등록하는 메서드는 register로부터 시작된다.

사실 실질적으로 등록되는 메서드는 아래 doRegisterBean 메서드이다.

doRegisterBean(Class , @Nullable String name,

@Nullable Class [] qualifiers, @Nullable Supplier supplier,

@Nullable BeanDefinitionCustomizer [] customizers)

/**

* Register a bean from the given bean class, deriving its metadata from class-declared annotations.

*/

명세에 위와 같이 주어진 Bean 클래스로부터 Bean을 등록하고 그 과정에서 클래스에 선언된 어노테이션을 기반으로 메타데이터를 가져온다고 적혀있다.

doRegisterBean은 우리가 이전에 정보를 등록한 AnnotatedBeanDefinitionReader 클래스 내부에 있다.

AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

먼저 AnnotatedGenericBeanDefinition의 인스턴스를 생성한다. (아규먼트는 beanClass)

AnnotatedGenericBeanDefinition가 핵심이므로 해당 클래스에 대한 상속 구조를 명확하게 해 두는 것이 좋을 것 같다.

GenericBeanDefinition

AbstractBeanDefinition

의 인스턴스 또한 함께 생성한다.

setBeanClass(beanClass);

AbstractBeanDefinition에 해당 클래스에 대한 정보를 저장한다.

메타데이터 가져오기

this.metadata = AnnotationMetadata.introspect(beanClass);

https://dahyeee.tistory.com/entry/JAVA-interface-default-static%EB%A9%94%EC%86%8C%EB%93%9C

AnnotationMetadata는 인터페이스이다. 해당 클래스 내부에 구현이 완성되어있는 introspect 메서드가 존재한다. 해당 메서드는 하위 클래스인 StandardAnnotationMetadata에게 메시지를 전달한다.

저장하는 정보는 SearchStrategy = INHERITED_ANNOTATIONS , nestedAnnotationsAsMap = True클래스에 대한 정보이다. (MergedAnnotations에 저장)

Scope 지정하기

AnnotationScopeMetadataResolver에 있는 Scope에 대한 메타 데이터를 가져와서 Scope을 지정한다.

private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

ScopeMetadataResolver는 인터페이스이고 AnnotationScopeMetadataResolver는 해당 인터페이스의 구현체이다.

따라서 아래와 같이 resolveScopeMetadata 메시지를 AnnotationScopeMetadataResolver에게 전달한다. 결과만 받으면 AnnotationScopeMetadataResolver가 어떻게 처리하든 상관하지 않는다.

ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

또한 결과를 ScopeMetadata라는 DTO 객체에 담아서 리턴한다는 점이 흥미롭다.

해당 DTO 객체는 디폴트 값으로 싱글톤이 설정되어있다.

실행 결과

빈 이름 설정하기

private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

위와 같다.

하지만 여기에선 싱글톤 형식으로 인스턴스를 여러 번 생성하지 못하도록 하였다.

private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

public static final AnnotationBeanNameGenerator INSTANCE = new AnnotationBeanNameGenerator();

해당 구조를 다시 상기시켜면서...

AnnotatedGenericBeanDefinition 은 BeanDefinition의 구체 클래스이므로

다형성을 활용하여 모든 타입은 BeanDefinition으로 받는다.

해당 과정을 통해 BeanName을 설정한다.

return buildDefaultBeanName(definition, registry);

내부의 과정은 bean의 이름을 가져와서 풀 패키지 경로를 클래스 명으로 줄이는 과정이다.

from http://jwdeveloper.tistory.com/190 by ccl(A) rewrite - 2020-03-06 22:21:23

댓글

이 블로그의 인기 게시물

데이터 바인딩 추상화 - propertyEditor

[샤니마스 SPRING PARTY2020] THE IDOLM @ STER SHINY COLORS SPRING...

Spring Web Form