Spring的启动过程(二)
LiuYang 2021/1/9 Spring Framework
之前的博客我们看了在ApplicationContext实例化的过程中,都创建了哪些内容,今天我们试着来理解一下
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
1
2
3
4
5
2
3
4
5
register的过程。
首先我们需要明确一下,componentClasses是什么,这其实就是我们在创建AnnotationConfigApplicationContext时传入的类。
new AnnotationConfigApplicationContext(AppConfig.class);
1
我们可以称为AppConifg
追踪代码我们发现,这里调用的还是我们的reader.register方法
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
this.reader.register(componentClasses);
registerComponentClass.end();
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
通过追踪代码,我们发现这里最后其实就是org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean方法
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
上面这个方法中,做了如下操作
- 将我们的beanClass转化称为一个BeanDefinition,用的还是BeanDefinition的构造方法
- 为这个BeanDefinition添加一些属性,尤其是processCommonDefinitionAnnotations方法更是添加了很多默认属性,这里的属性等等不再展开了。
- registerBeanDefinition方法追溯,最后还是找到registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); 这一行,这行代码我们之前是见过的,就是在之前初始化时,为beanFactory中beanDefinitionMaps添加BeanDefinition的put方法。我们就可以理解为,这里将我们自己的传过来的AppConfig.class也放入了beanDefinitionMaps之中,之前beanDefinitionMaps中已经存在了Spring初始化reader时放入的6个BeanDefinition了。这一步也是这里的核心功能。剩下一些记录别名之类的功能就不具体展开了。
# 一些 Spring 概念的自己理解
- BeanDefinition :存放 bean 定义相关信息,有点像 java 中的 Class。
- BeanDefinitionRegistry:BeanDefinition的注册器,由于ApplicationContext也实现了Registry的接口,所以可以实现为beanDefinitionMaps中添加BeanDefinition的功能等
- BeanDefinitionHolder:一种在Spring源码中便于传递的数据结构,主要属性就是beanDefinition,beanName,aliases