spring笔记⑧——spring源码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_35262405/article/details/100143813

AnnotationConfigApplicationContext相当于spring的环境对象,存放着spring的所有信息

AnnotationConfigApplicationContext初始化时,在调用自己的构造器时会先调用父类的构造方法

AnnotationConfigApplicationContext的父类是GenericApplicationContext在这里插入图片描述
会发现父类的构造方法new了一个DefaultListableBeanFactory对象,这个对象就是存放着许多重要信息的bean工厂
在这里插入图片描述
比如存放着beanName和bean的描述对象(bd)的map
在这里插入图片描述
放着所有的beanName的list
在这里插入图片描述
决定工厂中类的实例化顺序的比较器
在这里插入图片描述
接着就是AnnotationConfigApplicationContext自身的构造器,这里创建了两个对象,其中AnnotatedBeanDefinitionReader相当于bd的读取器,负责将需要生成的bean的类转换成bd放入spring容器,准确来说是放入上面的bean工厂中,但是这个对象只能读取加了注解的类
在这里插入图片描述

在这个reader的构造方法中也做了很多事情,这里传入了AnnotationConfigApplicationContext这个spring的环境对象,可以看出这个对象在reader中是个BeanDefinitionRegistry对象,可以称之为bd的注册器
在这里插入图片描述
进入到registerAnnotationConfigProcessors方法中发现它把工厂拿了出来,并且将上面工厂中的一些属性做了初始化设置
在这里插入图片描述
接着是将一些spring内部的bd放入到工厂中去,这里一共有7次添加,注意这里的bd对象是RootBeanDefinition,并且是直接通过构造器创建出来的,同时这里将bd和beanname做了一次封装,用BeanDefinitionHolder装了起来,这里是用registerBeanDefinition注册的
在这里插入图片描述
在这里插入图片描述
接下来就是创建了一个ClassPathBeanDefinitionScanner对象,这个对象主要是扫描类并转换成bd放到工厂中,就先不在着赘述了

回到register方法,进入这个register方法,发现这个方法调用了上面reader的register方法,最后经过层层调用执行doRegisterBean方法

这里同样将传进来的类的类对象转换成一个bd,中间的对这个bd初始化的过程就不再描述
在这里插入图片描述
最后依然是将这个bd和beanname组装成一个bdh,再通过registerBeanDefinition方法中注册器的registerBeanDefinition将这个bd注册到工厂中去,也就是put到了工厂的map中去了
在这里插入图片描述
紧接着就是refresh方法,这里第一个方法是初始化一些属性,第二个方法是拿到bean工厂,第三个方法是对bean工厂做一些处理,这个方法是重点
在这里插入图片描述
这里先是拿到了类加载器为后面的工作做准备哦,并设置了bean工厂的的一个用来解析bean的表达式的属性
在这里插入图片描述
这里向bean工厂添加了一个ApplicationContextAwareProcessor的后置处理器
在这里插入图片描述
添加了自动注入被忽略的列表
在这里插入图片描述
添加一些spring内部的实现类,不允许使用者自己注入,添加到bean工厂的一个map集合中
在这里插入图片描述
添加一个后置处理器ApplicationListenerDetector
在这里插入图片描述
空方法
在这里插入图片描述
一个很重要的方法,主要是处理实现了BeanFactoryPostProcessor的对象
在这里插入图片描述
这里拿到的是AnnotationConfigApplicationContext.addBeanFactoryPostProcessor中加入的BeanFactoryPostProcessor的实现类
在这里插入图片描述

spring初始化的流程调用链

//实例化一个工厂DefaultListableBeanFactory
org.springframework.context.support.GenericApplicationContext->GenericApplicationContext()
  	1、实力化一个AnnotatedBeanDefinitionReader
	2、ClassPathBeanDefinitionScanner,能够扫描我们bd,能够扫描一个类,并且转换成bd
	org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()
		委托AnnotationConfigUtils
		org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader()
			
			org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors()
			
				1、添加AnnotationAwareOrderComparator类的对象,主要去排序
				2、ContextAnnotationAutowireCandidateResolver
				3、往BeanDefinitionMap注册一个ConfigurationClassPostProcessor?  org.springframework.context.annotation.internalConfigurationAnnotationProcessor
					why?因为需要在invokeBeanFactoryPostProcessors
					invokeBeanFactoryPostProcessors主要是在spring的beanFactory初始化的过程中去做一些事情,怎么来做这些事情呢?
					委托了多个实现了BeanDefinitionRegistryPostProcessor或者BeanFactoryProcessor接口的类来做这些事情,有自定义的也有spring内部的
					其中ConfigurationClassPostProcessor就是一个spring内部的BeanDefinitionRegistryPostProcessor
					因为如果你不添加这里就没有办法委托ConfigurationClassPostProcessor做一些功能
					到底哪些功能?参考下面的注释
				4、RequiredAnnotationBeanPostProcessor
				.......
				org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors()
					//往BeanDefinitionMap注册
					org.springframework.context.annotation.AnnotationConfigUtils#registerPostProcessor
						//准备好bean工厂,实例化对象
						org.springframework.context.support.AbstractApplicationContext#refresh
						//准备工作包括设置启动时间,是否激活标识位, 初始化属性源(property source)配置
							org.springframework.context.support.AbstractApplicationContext#prepareRefresh
								//得到beanFactory?因为需要对beanFactory进行设置
								org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
									//准备bean工厂
									1、添加一个类加载器
									2、添加bean表达式解释器,为了能够让我们的beanFactory去解析bean表达式
									3、添加一个后置处理器ApplicationContextAwareProcessor
									4、添加了自动注入别忽略的列表
									5、。。。。。。
									6、添加了一个ApplicationListenerDetector后置处理器(自行百度)
									org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
										目前没有任何实现
										org.springframework.context.support.AbstractApplicationContext#postProcessBeanFactory
											1getBeanFactoryPostProcessors()得到自己定义的(就是程序员自己写的,并且没有交给spring管理,就是没有加上@Component2、得到spring内部自己维护的BeanDefinitionRegistryPostProcessor
											org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
												//调用这个方法
												//循环所有的BeanDefinitionRegistryPostProcessor
												//该方法内部postProcessor.postProcessBeanDefinitionRegistry
												org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
													//调用扩展方法postProcessBeanDefinitionRegistry
													org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
														//拿出的所有bd,然后判断bd时候包含了@Configuration、@Import,@Compent。。。注解
														org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
															1、的到bd当中描述的类的元数据(类的信息)
															2、判断是不是加了@Configuration   metadata.isAnnotated(Configuration.class.getName())
															3、如果加了@Configuration,添加到一个set当中,把这个set传给下面的方法去解析
															org.springframework.context.annotation.ConfigurationClassUtils#checkConfigurationClassCandidate
															//扫描包
															
															org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)
																
																org.springframework.context.annotation.ConfigurationClassParser#parse(org.springframework.core.type.AnnotationMetadata, java.lang.String)
																	//就行了一个类型封装
																	org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClass
																	1、处理内部类 一般不会写内部类
																	org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
																		//解析扫描的一些基本信息,比如是否过滤,比如是否加入新的包。。。。。
																		org.springframework.context.annotation.ComponentScanAnnotationParser#parse
																			org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
																			org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents
																				org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#scanCandidateComponents
																			//将扫描出来的bd注册到工厂中去
																			org.springframework.context.annotation.ClassPathBeanDefinitionScanner#registerBeanDefinition

猜你喜欢

转载自blog.csdn.net/qq_35262405/article/details/100143813