本仓库以 Spring 源码学习为目的,通过手写简化版 Spring 框架,了解 Spring 核心原理。关于过程中的笔记我放在了博客中
在手写的过程中会简化 Spring 源码,摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。整个项目涉及到的Bean生命周期如下图所示:
下面提供一个仓库目录,针对每一章都有一个博客来详细介绍项目中新增的内容
- 第一章:实现一个简单的
Bean容器 - 第二章:将
Bean的创建交给IOC容器 - 第三章:实现带参的
Bean创建 - 第四章:将
Bean的创建和属性填充分开 - 第五章:实现从配置文件中加载
Bean的注册信息 - 第六章:实现应用上下文,后置处理器
- 第七章:添加初始化和销毁模块
- 第八章:
Aware回调注入容器资源 - 第九章:多种模式以及多种方式创建
Bean对象 - 第十章:事件机制的实现
- 第十一章:引入
AOP机制 - 第十二章:自动扫描
Bean对象以及属性占位符的使用 - 第十三章:通过注解给
Bean注入依赖的属性 - 第十四章:通过延缓代理对象的创建时机从而给代理对象进行属性填充
- 第十五章:利用三级缓存解决循环依赖
经过上面的填充,简化版 Spring 框架已经有了一定的规模,下面介绍在Bean的生命周期中都加入了哪些模块:
-
首先
spring框架需要读取xml配置文件,然后将配置的所有Bean的注册信息保存到BeanDefinition中 -
之后就是触发实例化前的修改逻辑,内部可以将
Bean中使用占位符形式填充的属性换成真正的属性值。 -
下一步将实例化后的处理逻辑先保存到容器中,在实例化之后直接触发即可。
-
然后需要初始化一个事件广播器并将其保存到
IOC容器中,当事件发生时由事件广播器通知事件监听器从而执行对应的操作。 -
之后就是事件监听器的实例化,将其保存到上一步中的事件广播器中,事件经过事件广播器的发布之后,对应的事件监听器就会得到通知
-
然后进行所有
Bean的第一次实例化,在这一步加入了类型转换的服务,内部保存了很多的类型转换器,之后就是实例化所有的Bean -
第一次实例化所有的
Bean时,单例池中并没有需要的Bean,所以需要从头创建,首先创建一个空Bean,创建完成之后判断是不是FactoryBean类型的Bean,如果是的话需要从其中取出真正的Bean返回 -
将创建的空
Bean的信息保存到三级缓存中,便于后期出现循环依赖时使用,而循环依赖中会提前尝试AOP,从而得到Bean的原始对象或者代理对象。这也导致后面正常的AOP过程不一定会触发 -
三级缓存中,每一级缓存的作用都不相同,大致区别如下:
- 三级缓存:保存一个
lambda表达式,调用其中的getObject方法就能获得一个尝试代理之前的对象,用来打破循环依赖 - 二级缓存:用来保存尝试过代理后的
Bean,保持Bean的单例性 - 一级缓存:保存实例化完成之后的
Bean,便于复用,这里的Bean已经是完成态
- 三级缓存:保存一个
-
然后就是属性填充,有两种属性填充的方式,首先进行注解属性填充
-
然后进行普通的
xml文件配置的属性填充 -
之后使用
Aware回调机制实现容器资源的注入 -
之后执行初始化前的逻辑,主要是执行应用上下文的容器资源注入
-
初始化执行逻辑中主要是执行初始化方法,初始化方法有两种方式,一种实现对应的接口,一种是在
xml文件中配置指定初始化方法的名称 -
初始化后的逻辑中进行正常
AOP的操作,由于前面可能对Bean进行提前AOP,这里不一定触发 -
之后就是将销毁方法注册到钩子函数中,在容器销毁之前进行调用
-
经历上面的步骤之后,
Bean创建完成,之后将单例Bean保存到单例池中 -
后期再使用时走到第7步时就先尝试从单例池中拿,拿不到才会重新创建
以上的步骤只是精简过后描述的Bean的生命周期,细节需要查看提供的代码,代码在开发过程中参考了小傅哥的文章,从文章中受益匪浅。
