bean的生命周期源码解读

1、ClassPathXmlApplicationContext

创建spring以用程序上下文 	调用构造方法  	
1、调用父类的构造方法创建PathMathingResourcePatternReslover 解析配置文件 
 2、设置配置文件路径到当前应用程序中 	
 3、开始进入容器的创建和刷新环节 refresh();prepareRefresh 容器刷新前的准备工作;
			设置容器的启动时间
			设置活跃状态为true;
			设置关闭状态为false;
			
			initPropertySources();
			获取Environment对象,并加载当前系统的属性值到Environment对象中
			准备监听器和事件的集合对象,默认为空集合;

2、obtainFreshBeanFactory 创建容器,并且完成配置文件的加载

			1、createBeanFactory; 创建一个对象,DefaultListableBeanFactory
			2、beanFactory.setSerializationId;设置beanFactory的id;
			3、customizeBeanFactory:定制化beanFactory,有两个属性值
				 1、是否允许beanDefinition被覆盖
				 2、是否允许循环依赖;
			4、loadBeanDefinitions;加载配置文件,读取bean的定义信息;
					1、beanDefinitionReader-》XmlBeanDefinitionReader 读取beanDefinition,xml的属性信息定义在xsd约束文件里;schemas 
					2、设置当前系统的环境变量;environment
					3、设置资源加载器;
					4、设置实体处理器;解析配置文件的处理器;构造方法设置了schemas的地址;
					5、initDeifinitionReader,初始化当前reader对象,此处设置配置文件是否要进行验证
					6、loadBeanDefinition(beanDefinitionReader);
						1、获取当前配置文件的路径;
						2、xmlBeanDefinitionReder.loadDefinitions(String[]);传入的配置文件地址
							1、循环处理配置文件;
					7、doLoadBeanDefinitions (inputSource,encodeREsource.getResource())实际干活的方法,将配置文件解析成文档对象,方便通过父子节点的方式获取对应的标签元素
						1、doLoadDocument()将读取的配置文件的字符串读成一个document对象;解析完成之后包含一些节点信息
						2、registerBeanDefinitions(doc,resource);根据文档的读取信息,封装成beanDefinitions; 解析标签元素且完成注册功能; 
								1、BeanDefinitionMap:key:beanName value:BeanDefinition
								2、BeanDefinitionNames:存放beanDefinition的名称的集合
					8、doRegisterBeanDefinition(Element root) 实际完成注册操作
							1、createDelegate();
							2、parseBeanDefinition 解析beanDefinition
								1、遍历外层标签中 子标签,然后开始判断用什么样的方式进行解析操作
								2、默认的命名空间,有默认的标签。bean、import、alias等;使用默认的方式进行解析;parseDefaultElement 
								3、使用额外的方式进行解析;parseCustomElement;
									1、跟进当前标签的命名空间字符串查找对应的hanlder处理类;spirng.handlers
									2、通过不同的handler对象去解析不同的标签元素 handler.parse不同的标签有不同的处理类,具体的处理逻辑可能不同,但是最终都会获取到完成的beanDefinition
									3、创建genericBeanDefinitions
								4、将解析完成的BeanDefinition对象注册到容器的BeanDefinitionMap和BeanDefinitionNames集合中

3、prepareBeanFactory给容器对象完成属性的赋值操作

			1、设置bean加载器
			2、设置ExpresssionResolver spel表达式解析器
			3、addPropertytEditorRegister 属性编辑器 参数对应解析类;
			4、beanPostProcessors (new ApplicationContextAwareProcessor(this))集合 bpp在bean实例化之后进行相关的操作,ApplicationContextAwareProcessor完成某些aware对象的注入
		
			5、ignoredDependenceInterfaces 忽略依赖的接口;第四步已经处理的进行忽略;
			6、registerResolvableDependencies 设置几个自动装配的特殊规则,在进行ioc初始化时如果有多个实现,那么就是用指定的对象进行注入;例如@Primary
			7、singletonObjct

4、postProcessBeanFactory 默认没有实现,留给子类进行实现操作

扩展时继承这个类,重写这个方法即可;

5、invokeBeanFactoryPostProcessor 执行bfpp接口中的方法

		自定义的话可以调用具体的add方法或者在xml里进行bean的定义;
		BeanDefinitionRegistryPostProcessor 是BeanFactoryPostProcesser的子类;
			1、可以自用扩展,修改beanFactory中的相关信息,但是使用最多的是对BeanDefintion的修改操作 
					1、ConfigurationClassPostProcessor !!!!很重要,能完成注解的一个使用;方法:processConfigBeanDefinitions(registry)吃力配置类的定义信息;@Configuration @Bean @Import @Component @ComponentScan @ComponentScans;
					2、PropertySourcePlaceHolderConfigurer
			2、创建一个空的集合,用来存储执行过的BFPP;
			3、判断当前beanFactory是否是BeanDefinitionRegistry 创建两个空的集合对象,分类存储BFPP和BDRPP
			4、是;处理用户传进来的自定义的BFPP;便利每一个元素集合,
				1、判断是否是BeanDefintionRegistryPostProcessor子类;
				2、进行类型转换,执行BDRPP接口中的方法
				3、放到regularPostProcessor集合中;
			5、创建存放BDRPP的集合对象用来存储当前正在执行过程中的BDRPP
			6、获取当前容器中国所有实现了BDRPP的对象 BeanDefinitionRegistryPostProcessor;
					1、判断是否实现了 priorityOrdered接口
							是 添加具体对象到currentRegistryProcessor集合中,并且将当前bdrpp的名字加入processedBeans中
					2、将currentRegistryProcessors进行排序操作
					3、将currentRegistryProcessors集合中的属性值合并到registryProcessors
					4、执行bdrpp接口中的方法 inbokeBeanDefinitionRegistryPostProcessors
					5、清空当前currentRegistryProcessors;
			7、获取当前容器中所有实现了bdrpp接口的对象,并且判断是否实现orderd接口;
					跟6的流程一样;
			8、获取当前容器中所有实现了BDRPP接口的对象,如果没有实现PriorityOrdered接口,也没有实现Ordered的接口
					跟6的流程一样
			9、执行所有RegistryProcessors中对象的PostProcessBeanFactory接口的方法
			10、执行所有regularProcessors中对象的postProcessorBeanFactory接口方法
			11、优先处理实现了PriorityOrderd接口的BFPP对象,然后是Orderd接口的对象,最后是两者都没有实现的对象
					调用BFPP中的postProcessorBeanFactory方法

6、注册BeanPostProcessorRegistryBeanPostProcessor(BeanFactory)

			1、完成spring自带或者用户自定义的BeanPostProcessor的解析

7、initMessageSource 进行国际化相关的操作 MessageSource.Locale

8、initApplicationEverntMulticaster() 初始化事件广播器

		使用监听者模式
		1、创建多个事件类
		2、注册多个事件类
		3、初始化广播器
		4、创建多个监听器
		5、注册多个监听器
		6、事件发布,通知广播器进行广播
		7、监听器监听处理

9、onRefresh

			1、在spring中默认没有任何实现、模板方法,但是在spirngboot中启动了web容器

10、registerListerners() 注册监听器

			1、为了方便接受广播事件

11、finishBeanFactoryInitialization(beanfactory)完成所有非懒加载的单例对象的实例化操作

getBean->doGetBean->createBean->doCreateBean
			从此方法开始进行对象的创建、包含了实例化、初始化、循环依赖、aop等核心逻辑的处理过程,此步骤是最核心关键点。
			1、为上下文初始化类型转换器  converterService;
				有三种转换器的实现方式:
				converter s到t的转换
				genericConverter 用于两种或者更多中类型之间转换的通用转换器接口
				converterFactory converter转换器的工厂类,用来获取对应的转换器
			2、如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
			3、尽早初始化loadTimeWeavweAware bean,以便尽早注册他们的转换器
			4、禁止使用临时类加载器进行类型匹配
			5、冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
			6、实例化剩下的单例对象;
					1、将所有的beanDefinition的名字创建一个集合
					2、触发所有非延迟加载单例bean的初始化,遍历集合的对象 、合并父类beanDefinition
						getMergedLocalBeanDefinition:在实例化之前,要把所有的基础的beanDefinition对象转化成RootBeanDefinition对象,进行缓存。后续在需要马上实例化的时候,直接获取定义信息,而定义信息中如果包含了父类,那么必须要先创建父类才有子类。
						是否是factoryBean(如果使用beanFactory的接口,那么必须要严格遵守spring的bean的生命周期接口,从实例化,到初始化。此流程非常复杂且麻烦,如果有需要有一种更加便捷简单的方式创建,所以使用factoryBean这个接口,不需要遵循Spring的生命周期)
						factoryBean 有三个方法:
						getObjectType 返回类型
						getObject 直接返回对象 加&返回实现factoryBean的对象,否则返回bean对象
						isSingleton 是否单例
						当使用factoryBean接口来创建对象的时候,一共创建了两个对象,1:实现了factoryBean接口的子类对象2:通过getObject方法返回的对象。此对象的创建过程就是由getObjectForBeanInstance方法调用实现的。都交给spring管理,但是object对象放到factoryBeanObjectCache内,FactoryBean放到singletonObjects一级缓存中。(earlySingletonObjects是二级缓存;singletonFactories 三级缓存; )如果不是单例对象,那么需要每次调用的时候重新创建,缓存中不会保存当前对象

12、finishRefresh 完成刷新

				1、完成整个容器的启动,所有的对象都准备完成,可以进行后续业务流程的操作,清除上下文缓存,初始化生命周期处理器、发送刷新完成事件

13、resetCommonCaches清空运行过程中产生的缓存

			如果运行过程中出现异常清空
				1、销毁前面过程中创建的bean对象
				2、重置当前容器的状态标致
				3、抛出异常
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值