https://jwdeveloper.tistory.com/189
이때까지 살펴보았던 과정은 인스턴스를 생성하거나 초기화하는 과정이었다.
이제 실질적으로 Bean을 등록하는 과정을 살펴보자
Bean을 등록하는 메서드는 register로부터 시작된다.
사실 실질적으로 등록되는 메서드는 아래 doRegisterBean 메서드이다.
doRegisterBean(Class <T>, @Nullable String name,
@Nullable Class <? extends Annotation>[] qualifiers, @Nullable Supplier <T> 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의 이름을 가져와서 풀 패키지 경로를 클래스 명으로 줄이는 과정이다.
refresh()
'Spring > Spring' 카테고리의 다른 글
(SPRING) Dynamically register bean (0) | 2020.03.22 |
---|---|
(SPRING) 빈의 스코프 (0) | 2020.03.22 |
(SPRING) Spring ApplicationContext의 내부 (1) (1) | 2020.03.01 |
(SPRING) IoC 컨테이너 - Environment_프로파일 (0) | 2020.02.14 |
(SPRING) IoC 컨테이너 - 빈의 스코프 (0) | 2020.01.01 |