Spring源码分析

Spring源码分析

AnnotationConfigApplicationContext

反推猜测应该完成什么?

  1. 生成bean对象 -> 创建beanFactory (bean工厂)
  2. BeanDefinition类 (加载bean信息, 通过注解得来的信息) -> 注解配置解析器AnnotationBeanDefinitionReader类

AnnotationBeanDefinitionReader中读取到不同的注解,有一系列的注解解析器去解析不同的注解

  1. 类路径扫描器 ClassPathBeanDefinitionScanner
  2. 系统属性扫描器 …

深入AnnotationConfigApplicationContext注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { // 配置类可以有多个
// 调用无参数构造函数, 初始化三个重要对象
// 1. DefaultListableBeanFactory工厂: 生成bean对象的beanFactory工厂
// 2. AnnotatedBeanDefinitionReader: 对加了特定注解(如@Service、@Repository)的类进行读取转换为BeanDefinition对象
// 还要注册各种处理器: registerAnnotationConfigProcessors(), 通过此方法添加各种内置处理器, 其中最重要的:
// 2.1 ★ConfigurationClassPostProcessor 是一个beanFactory后置处理器,用来完成bean的扫描与注入
// 2.2 AutowiredAnnotationBeanPostProcessor是一个bean的后置处理器, 依赖完成@Autowired自动注入
// 3. ClassPathBeanDefinitionScanner:对用户指定的包目录进行扫描查找bean对象的路径 扫描
this();
// 利用AnnotatedBeanDefinitionReader取将传进来的Configuration类做解析
// 将配置类Configuration注册到容器,但不实例化,其中最核心的方法为:doRegisterBean()
this.register(componentClasses);
// ***容器刷新*** @ComponentScan在这里完成解析
this.refresh();
}

this类中托管的各种注解解析器bean

this()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public AnnotationConfigApplicationContext() {
super();//调用父类无参数构造方法,省略了
// startupStep类: 记录Application启动期间发生的特定阶段和操作的度量指标
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 生成并注册BeanDefinition
// 配置类
//1.org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// 自动配置
//2.org.springframework.context.annotation.internalAutowiredAnnotationProcessor
// 特定注解
//3.org.springframework.context.annotation.internalCommonAnnotationPostProcessor
// 事件监听
//4.org.springframework.context.event.internalEventListenerProcessor
// 工厂
//5.org.springframework.context.event.internalEventListenerFactory
this.reader = new AnnotatedBeanDefinitionReader(this);// 注解bean读取
createAnnotatedBeanDefReader.end();
// 注册默认的includeFilter
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

至此发现还少了一个DefaultListableBeanFactory的工厂创建

构建工厂

super()

点进父类 (GenericApplicationContext) -> super()

1
2
3
4
5
6
public GenericApplicationContext() {
this.customClassLoader = false;
this.refreshed = new AtomicBoolean();
// 父类构造器中创建了一个bean工厂,默认列表bean工厂
this.beanFactory = new DefaultListableBeanFactory();
}

到这发现我们猜想的三个功能在this()中全部找到

注册各种处理器

this.reader = new AnnotatedBeanDefinitionReader(this)

注册处理器, 点进去

1
2
3
4
5
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
// 创建系统 属性及环境变量 getOrCreateEnvironment()
// 查看this(xx,yy)构造方法
this(registry, getOrCreateEnvironment(registry));
}

构造方法this(xx,yy),点进去

1
2
3
4
5
6
7
8
9
10
11
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
// 内部类用于解析 @Conditional注解
this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null);
// 注册多种内置注解配置解析器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

深入AnnotationConfigUtils.registerAnnotationConfigProcessors(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
39
40
41
42
43
44
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, (Object)null);
}

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
// 创建Bean工厂 beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
// 逐步追加一些默认组件
// 第一个追加的组件 AnnotationAwareOrderComparator
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
// 对@Order、@Priority、Ordered接口进行排序的比较类
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}

if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
// @Autowired @Qualifier @Lazy注解解析器
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// BeanDefinitionHolder: 有名字和别名的
Set<BeanDefiniti onHolder> beanDefs = new LinkedHashSet(8);
RootBeanDefinition def;
// 判断容器是否有internalConfigurationAnnotationProcessor 这个bean
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
// 创建一个配置类处理器,托管成Bean ConfigurationClassPostProcessor
def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
// 补充一个属性值 source
def.setSource(source);
// 在registerPostProcessor()中将 RootBeanDefinition 包装成 BeanDefinitionHolder, 为什么?
// BeanDefinition添加了alias(别名)
// 另外, 注册此bean到容器是在 在registerPostProcessor完成的 (仅仅是加载到容器中)
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
}

if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
// 没有则创建 AutowiredAnnotationBeanPostProcessor 并且托管
def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
}
// 省略其他的处理器,当前仅留俩个样例
return beanDefs; // 返回BeanHolderProcess集合
}
梳理一下:

super() : 初始化bean工厂

new AnnotatedBeanDefinitionReader(this) : 创建各种各样的处理器

register注册配置类

注册@Configuration类

this.register(componentClasses)

1
2
3
4
5
6
7
8
9
10
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", () -> {
return Arrays.toString(componentClasses);
});
// 注册配置类 (点进去)
this.reader.register(componentClasses);
registerComponentClass.end();
}

this.reader.register(componentClasses);

1
2
3
4
5
6
7
8
9
10
public void register(Class<?>... componentClasses) {
Class[] var2 = componentClasses;
int var3 = componentClasses.length;
// 循环遍历componentClass组件类
for(int var4 = 0; var4 < var3; ++var4) {
Class<?> componentClass = var2[var4];
// 注册bean
this.registerBean(componentClass);
}
}

真正注册bean 的方法

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
// 解析包装传入的 Configuration类,变成AnnotatedGenericBeanDefinition对象
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 判断是否要跳过,判断依据是此类上是否有@Conditional注解
if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
// 回调函数
abd.setInstanceSupplier(supplier);
// Scope值
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
// 默认设置scope是singleton
abd.setScope(scopeMetadata.getScopeName());
// 如果有定义bean的名字则用定义的,否则则获取并生成
String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);
// 处理类上面的通用注解: 如@Lazy @Primary @DependsOn,解析出左边的注解,保存到BeanDefinition中
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
int var10;
int var11;
if (qualifiers != null) {
Class[] var9 = qualifiers;
var10 = qualifiers.length;

for(var11 = 0; var11 < var10; ++var11) {
Class<? extends Annotation> qualifier = var9[var11];
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
// 用户自定义注解
if (customizers != null) {
// 类必须实现BeanDefinitionCustomizer接口
BeanDefinitionCustomizer[] var13 = customizers;
var10 = customizers.length;

for(var11 = 0; var11 < var10; ++var11) {
BeanDefinitionCustomizer customizer = var13[var11];
customizer.customize(abd);
}
}
// 到此还没有实例化,仅仅是构建了一个BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 应用scopeProxyMode 代理模式
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 把BeanDefinitionHolder注册到registry容器中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
// registerBeanDefinition注册bean
}
}
梳理一下:

三步:

  1. this()注册了默认的Bean
  2. register()注册配置类的Bean (registerBeanDefinition()方法)
  3. 那么还剩一个refresh则是用于 注册自定义的Bean

refresh()所有的 bean 的创建以及初始化

Spring的refresh()方法会触发所有bean的创建初始化过程。当调用refresh()方法时,Spring容器会执行一系列的步骤,包括创建BeanFactory、加载Bean定义、实例化Bean、依赖注入、初始化Bean等。

refresh()方法中,Spring会遍历所有注册的Bean定义,根据定义创建相应的Bean实例,并对这些实例进行初始化。这个过程包括调用Bean的构造函数创建实例,设置Bean的属性值,执行Bean的初始化方法等。这样,所有的Bean都会经过这个过程,完成它们的创建和初始化。

需要注意的是,refresh()方法并不会销毁已经存在的Bean实例。它主要用于重启Spring容器,重新加载和初始化Bean。如果需要销毁已经存在的Bean实例,可以使用destroy()方法或者通过配置合适的作用域(如prototype)来控制Bean的生命周期。

非常重要的方法 invokeBeanFactoryPostProcessors bean工厂的后置处理器

Refresh()

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {// 设置同步标识
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
// 1. 调用容器准备刷新的方法, 获取容器的时间,包括设置上下文状态,获取属性,验证必要的属性等
// ▶可以实现initPropertySources()方法, 添加属性或设置需要验证的属性
this.prepareRefresh();
// Tell the subclass to refresh the internal bean factory
// 2. ★★★★★获取新的beanFactory,刷新BeanFactory和获取getBeanFactory --> 获取IOC容器
// 如果在这里断点,只会发现它仅仅完成了beanFactory设置序列化id
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// Prepare the bean factory for use in this context, 为BeanFactory配置容器亏秤,如类加载器,事件处理器
// 3. 填充BeanFactory功能, 配置容器特性
// 例如设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加三个和环境相关的bean (SpEL: 例如@Value("#{name}"))
// 添加两个bean后置处理器BeanPostProcessor(ApplicationContextAwareProcessor和ApplicationListenerDetector)等
this.prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses
// 4. 在这里是空方法(模版语法),子类可以重写这个方法,可以在BeanFactory创建并与准备完成后做进一步的设置
// 即子类处理自定义的BeanFactoryPostProcess
this.postProcessBeanFactory(beanFactory);// 为容器的子类指定特殊的post事件处理器
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
/*
以下两点是关于后置处理器的激活
Spring中会发现有很多后置处理器,但最终可以分为两种
(1)BeanFactoryPostProcessor,用于干预BeanFactory的创建过程
(2)BeanPostProcessor,用于干预Bean的创建过程
后置处理器的作用非常重要,Bean的创建以及AOP的实现全部依赖后置处理器
*/
// Invoke factory processor registered as beans in the context
// 5. ★★★★★ 激活各种BeanFactory处理器,调用所有注册的BeanFactoryPostProcessor的Bean
// BeanFactoryPostProcessor可以在工厂初始化后,让用户做一些定制型的工作.(实现此BeanFactoryPostProcessor接口)
// 执行所有的BeanFactoryPostProcessor,包括自定义的,以及Spring内置的
// 默认情况下,容器中只有一个BeanFactoryPostProcessor,即Spring内置的ConfigurationClassPostProcessor(★这个类很重要)
// 会先执行实现了BeanDefinitionRegistryPostProcessor接口的类,然后执行BeanFactoryPostProcessor的类
// ★★★★ ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法进行了@Configuration类的解析,@ComponentScan的扫描,@Import注解的处理
// 进过了这一步以后,会将所有交由Spring管理的bean对应的BeanDefinition放入beanFactory的beanDefinitionMap中
// 同时ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法执行完后:
// 向容器中添加了一个后置处理器-- ImportAwareBeanPostProcessor
this.invokeBeanFactoryPostProcessors(beanFactory);//★★★★★★ 及其重要,在这里完成了 @ComponentScan的扫描,@Import注解的处理
// Register bean processor that intercept creation.
// 6. ★★★注册BeanPostProcessor后置处理器
// AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean,并注入)
// RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
// CommonAnnotationBeanPostProcessor(处理@PreDestroy @PostConstruct @Resource等多个注解的作用)等
// AutoProxyCreator(处理AOP代理 @Aspect)
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 7. 初始化信息源(做国际化功能: 消息绑定,消息解析)
this.initMessageSource();
// 8. 初始化事件派发器,在注册监听器时会用到
this.initApplicationEventMulticaster();
// 9. 这也是一个挂载点,一个空方法,由子类实现(不同的Spring容器做不同的实现),在容器监听的时候可以自定义逻辑
this.onRefresh();
// 10. 注册监听器,派发之前步骤产生的一些事件(尽可能没有)
this.registerListeners();
// 11. ***** 初始化剩下的单例Bean(非延时加载的) 真正的初始化bean的方法
this.finishBeanFactoryInitialization(beanFactory);
// 12. 初始化容器的生命周期事件处理器,并发布容器的生命周期事件
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}

this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}

}
}

@ComponentScan属性的读取

逐步读取

目标: 读取basePackages设置的类

寻找的目录指引如下:(以下每一步操作均为追踪描述方法后的指引介绍)

  1. 入口 AnnotationConfigApplicationContext
  2. 当前类下的构造器实现重载解析类的方法 找到refresh(),
  3. ★invokeBeanFactoryPostProcessors方法(重要),
  4. 然后可以找到一个后置处理器的委托代理类 (PostProcessorRegistrationDelegate) ,其中有方法为invokeBeanFactoryPostProcessors
  5. 在当前方法中找到 if-else中的invokeBeanFactoryPostProcessors方法(中间处理bean工厂类上加了注解的,比如@Primary,@Order排序), 不论走if还是else 都会激活bean工厂的后置处理器

invokeBeanFactoryPostProcessors

  1. 找到postProcessor.postProcessBeanFactory(beanFactory)这一行, 当前行为后置处理器处理bean工厂, 点进postProcessBeanFactory方法发现什么都没有, 他是一个@FunctionalInterface接口(函数接口), 找实现类(如下图),
  1. 找到 postProcessBeanFactory 方法(bean工厂的后置处理器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);
} else {
this.factoriesPostProcessed.add(factoryId);
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then
// 判断已注册的PostProcessor是否包含了factoryId
if (!this.registriesPostProcessed.contains(factoryId)) {
// ★正式处理配置Bean定义 @Configuration -> 里面带了一个@ComponentScan
this.processConfigBeanDefinitions((BeanDefinitionRegistry)beanFactory);
}
// 代理
this.enhanceConfigurationClasses(beanFactory);
// Import感知 @Import({A.class})
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
}
  1. 追踪processConfigBeanDefinitions
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList();
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
// 迭代所有候选的bean名字
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 判断上面是否包含ConfigurationClass属性
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
// 略 (如果有则加入候选)
}

if (!configCandidates.isEmpty()) {
// 配置类候选排序(@Order,@Priority排序标志)
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
// 检查是否为单例bean
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry)registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
// 环境,如果没有则标准环境
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
// ★★★★解析每一个@Configuration类,包括@ComponentScan
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 上述配置类解析器包括:注解元信息的读取工厂、问题报告器、标准系统环境变量、资源加载器、组件扫描bean名字构建器
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet(configCandidates.size());

do {// 一个一个的读取候选的配置(可以有多个配置类,一次读取一个)
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
// ★★★★★★ 真正的解析器在此
parser.parse(candidates); // candidate 候选集合(多个配置类)

parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
// 下面代码略
}
}
  1. 追踪parse (8中源码注释标★★★★★★)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void parse(Set<BeanDefinitionHolder> configCandidates) {
Iterator var2 = configCandidates.iterator();
// 循环迭代每一个Configuration类,parse()解析
while(var2.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
BeanDefinition bd = holder.getBeanDefinition();
// 开始判断注解属于什么类
try {
if (bd instanceof AnnotatedBeanDefinition) {
this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
} else {
this.parse(bd.getBeanClassName(), holder.getBeanName());
}
}
// catch异常处理处(略)
}
this.deferredImportSelectorHandler.process();
}

在此处总结发现, 源码中凡是嵌套if-eles的, 最后都会调用 同一个方法, 方法的重载

  1. 继续追踪重载的parse
1
2
3
4
5
6
7
protected final void parse(@Nullable String className, String beanName) throws IOException {
Assert.notNull(className, "No bean class name for configuration class bean definition");
// 元数据读取
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
// ★ 处理配置类
this.processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
}
  1. 追踪processConfigurationClass,★★★★★然后追踪do-while里面的递归处理配置类

在此处先是处理条件注解@Conditional, 然后判断配置类, 没导入则合并 marginImport

do-while中递归读取配置类方法doProcessConfigurationClass.

在@Configuration注解中它包括了@Component注解.

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
// 第一步判断配置类上是否有@Component注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
this.processMemberClasses(configClass, sourceClass, filter);
}
// 属性资源读取 (eg: @PropertySource("classpath:db.properties"))
Iterator var4 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();

AnnotationAttributes importResource;
while(var4.hasNext()) {
importResource = (AnnotationAttributes)var4.next();
// 有则处理
if (this.environment instanceof ConfigurableEnvironment) {
this.processPropertySource(importResource);
} else {
this.logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// ★★★★★目标到达★★★★★
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
// 如果包扫描注解不是空 并且 不跳过
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
// 迭代器遍历包扫描的注解
Iterator var14 = componentScans.iterator();

while(var14.hasNext()) {

AnnotationAttributes componentScan = (AnnotationAttributes)var14.next();
// The config class is annotated with @ComponentScan -> perform the scan immediatel
// ★★★★★ 这个parse真正处理@ComponentScan中的basePackages
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
Iterator var8 = scannedBeanDefinitions.iterator();
// Check the set of scanned definitions for any further config classes and parse recursively if needed
while(var8.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var8.next();
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}

if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
this.parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// @Import
this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
// 略
return null;
}

对于上述源码的parse:

  1. 首先建立了一个ClassPathBeanDefinitionScanner扫描器, 扫描@ComponentScan, 以及是否要过滤(includeFilters)

  2. 包扫描器获取名字, 获取作用域(设置), 资源模式, 扫描过滤条件(包含过滤器,扫描过滤器), 判断是否为懒加载(lazyInit)

  3. ★★★★★ 期盼的 (扫描basePackages)

    1
    2
    3
    4
    5
    // 情况一 basePackages
    Set<String> basePackages = new LinkedHashSet();
    String[] basePackagesArray = componentScan.getStringArray("basePackages");
    // 情况二 basePackageClasses
    Class[] var20 = componentScan.getClassArray("basePackageClasses");
  4. 判断是否为空, 假如为空, 则获取当前注解类的包路径

  5. 最后看看是否有筛选, 过滤

到此,包名准备完毕, 然后 递归扫描

1
return scanner.doScan(StringUtils.toStringArray(basePackages));

doScan递归扫描

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
1. 资源扫描
扫描包路径下.class文件, 将资源转换为Resource
2. 资源加载
通过ASM框架获取class元数据,封装BeanDefinition
3. 资源解析
获取bean上注解的属性值, 如@Scope
4. 生成Bean
生成beanName, 设置Bean默认值(懒加载,初始化方法等) 代理模式
5. 注册Bean
把BeanDefinition放入IOC容器DefaultListableBeanFactory
*/
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//创建一个集合,存放扫描到的Bean定义封装类
// 无序,不可重复, BeanDefinitionHolder包了一个BeanDefinition: bean的定义类:关于一个bean所有的相关信息
// (scope,lazy,initmethod,destroymethod...)
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
//遍历扫描所有给定的包路径
for (String basePackage : basePackages) {
//** 调用父类ClassPathScanningCandidateComponentProvider的方法
// 扫描指定类路径, 获取符合条件的Bean定义, 并存入集合beanDefinitions中
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
//遍历BeanDefinition (扫描到的bean)
for (BeanDefinition candidate : candidates) {
//** 获取@Scope的值,即获取scope的作用域, scope取值: singleton,prototype
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
// 为bean 设置作用域
candidate.setScope(scopeMetadata.getScopeName());
//** 为bean生成名字
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
// 设置Bean的自动依赖注入装配属性等 ****这里每一个bean 先设置默认值(lazy,autowiredMode,dependency,init,destroy)
if (candidate instanceof AbstractBeanDefinition) {
//* -> applyDefaults 给默认值设置一个bean的属性
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
// 如果扫描到的bean是Spring的注解bean,则处理其通用的Spring注解
// 再设置这个bean上的用户配置值
if (candidate instanceof AnnotatedBeanDefinition) {
//** 解析通用注解(@Lazy、@Primary、@DependsOn、@Role、@Description注解),为这些注解设置值
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 冲突检查
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);

//** 在容器中注册扫描到的bean
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}

简化注册扫描

以往

1
2
ApplicationContext context =
new AnnotationConfigApplicationContext(SpringConfig.class);

通过读取配置类, 然后读取配置类上面的@ComponentScan注解, 然后在扫描

现在

1
2
ApplicationContext context =
new AnnotationConfigApplicationContext(basePackages = "com.spring");

通过使用AnnotationConfigApplicationContext的重载方法, 直接扫描指定的basePackages路径, 省略了读取配置类在读取注解的流程

使用这个方案, 也就是直接走到了 scanner.doScan(StringUtils.toStringArray(basePackages));方法而不需要绕来绕去的解析

缺点: 路径固定

上部分小总结

refresh

实例化(循环依赖)

流程了解

既然都得到了扫描到的对象 Set<BeanDefinition>

接下来需要做的就是实例化对象了

其中实例化包括

  1. @Value 设置属性
  2. @Autowired 注入依赖

然后 存入map

通过getBean()获取IOC容器中的bean

从容器中取的流程:

  • 懒加载模式: content.getBean() -> getBean -> doGetBean()
  • 非懒加载模式: finishBeanFactoryInitialization() -> beanFactory.preInstantiateSingletons() 生成一个单例bean -> getBean() -> doGetBean()

所以两类都是殊途同归 doGetBean()

如何解决循环依赖

循环依赖, 依赖成为一个环, 互相依赖

构造方法循环依赖
  1. 在构造器循环依赖的每一个构造器上面加注解@Lazy

  2. 代码重构

  3. 改为字段依赖注入

使用注意点是:

@Lazy注解:

  • 初始化注入代理对象时, 真实调用时使用Spring AOP动态代理去关联真实对象, 然后通过反射完成调用
  • 加在构造器上, 作用域为构造器所有参数, 加在某个参数上, 作用域为该参数
  • 作用在接口上, 使用JDK动态代理, 这样在类上, 使用CGLib动态代理
Setter循环依赖

字段注入循环依赖,Spring官方通过三层缓存解决, 解决方案:

setter注入下 实例化 (无参构造方法) 和依赖属性注入**(set或属性)**是分开的, 这是其可以解决循环依赖最根本的原因

getBean中创建Bean的流程
doGetBean()
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
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 根据指定的名称获取被管理的Bean的名字, 剥离指定名称中对容器的相关依赖
// 如果指定的是别名,那么将别名转换为规范的Bean名称
// <1>获取beanName: 传入参数name可能是别名,也有可能是FactoryBean, 所以需要一系列的解析
// 为FactoryBean时,name为 "&工厂名" ,还要别名的情况
String beanName = transformedBeanName(name);
Object beanInstance;

// Eagerly check singleton cache for manually registered singletons.
// 从缓存中获取已被创建过的单例Bean
// ***<2>从缓存中获取单例bean,避免循环依赖
Object sharedInstance = getSingleton(beanName);// 单例模型 (getSingleton方法看下面源码部分)
// 如果缓存中有此单例Bean
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else{
// 省略
}
finally {
beanCreation.end();
}
}

return adaptBeanInstance(name, beanInstance, requiredType);
}
getSingleton()

只有单例才会有这个,原型模式不会调用此方法

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
39
40
41
42
43
44
45
46
47
48
// Spring对单例的bean只会创建一次,后续获取则都是在缓存中获取
// 该过程体现在 #getSingleton(String beanName)中
/*
三级缓存机制的理解: 目标避免循环依赖
一级: 从singletonObjects获取实例
否则:从earlySingletonObjects获取
否则: 从singletonFactories获取beanName对应的ObjectFactory,在调用getObject()来创建bean,并放到earlySingletonObjects中
并从singletonFactories中删除此ObjectFactory
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 从单例缓存(一级缓存)中获取单例bean: 用来存已经完成初始化的单例bean
Object singletonObject = this.singletonObjects.get(beanName);
// 如果缓存中没有 并且 该bean真正创建(在singletonsCurrentlyInCreation集中存在此bean的名字)
// ★★★ isSingletonCurrentlyInCreation(beanName)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 从二级缓存earlySingletonObjects中取 已经创建但是没有属性注入
singletonObject = this.earlySingletonObjects.get(beanName);
// earlySingletonObjects中没有,且运行提前创建
if (singletonObject == null && allowEarlyReference) {
// 双重检查锁

// 防止重复创建,使用正式创建bean前锁定(单例模型的双重检查锁:当前判断了两次singletonObject,在锁之前和锁之后)
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// earlySingletonObjects中没有,且运行提前创建
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 从三级缓存 singletonFactories 中获取对应的ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 从单例工厂中获取bean
singletonObject = singletonFactory.getObject();
// 存入(early, 注意此时还没有添加属性(populateBean用来注入属性的),添加到二级缓存)
this.earlySingletonObjects.put(beanName, singletonObject);
// 从三级缓存中删除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}

三级缓存的理解:目标避免循环依赖
一级: 从singletonObjects获取实例
二级——>否则:从earlySingletonObjects获取
三级————>否则: 从singletonFactories获取beanName对应的ObjectFactory,在调用getObject()来创建bean,并放到earlySingletonObjects中
——————>并从singletonFactories中删除此ObjectFactory


一级缓存(singletonObjects): 是一个完整的Bean -

二级缓存(earlySingletonObjects): bean的实例,但是没有属性( 属性还没有注入,所以说构造方式没办法解决循环依赖,set注入可以 ) , 早期的bean

三级缓存(singletonFactories ): 存放bean的原始工厂,其内容与二级缓存中的无异

Spring解决循环依赖(在此仅考虑set/属性注入,单例情况)是依靠Bean的中间态(一级:完整bean 二级:没有属性的bean 三级;ObjectFactory)这个概念, 而中间态是指bean的初始化状态

实例化的过程又是通过构造器创建的,如果A还没创建出来就不能提前曝光(对象工厂,三级缓存ObjectFactory), 所以构造器的循环依赖无法解决


双重检查锁: 单例, 在一级缓存和二级缓存后加锁,加锁后再走一遍判断一级二级缓存中是存在singletonObject对象