Skip to content

🌼🌻🌷从零实现一个小型的spring框架,通过手写spring源码来理解spring中的重要知识点。主要包括IOC,资源感知注入,对外扩展,AOP,事件机制等内容。

Notifications You must be signed in to change notification settings

zzziCode/small-spring

Repository files navigation

📢📢📢 学习说明

​ 本仓库以 Spring 源码学习为目的,通过手写简化版 Spring 框架,了解 Spring 核心原理。关于过程中的笔记我放在了博客

​ 在手写的过程中会简化 Spring 源码,摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOCAOPBean生命周期、上下文、作用域、资源处理等内容实现。整个项目涉及到的Bean生命周期如下图所示:

spring-life-cycle

📑📑📑 章节目录

​ 下面提供一个仓库目录,针对每一章都有一个博客来详细介绍项目中新增的内容

🏁🏁🏁 总结

​ 经过上面的填充,简化版 Spring 框架已经有了一定的规模,下面介绍在Bean的生命周期中都加入了哪些模块:

  1. 首先spring框架需要读取xml配置文件,然后将配置的所有Bean的注册信息保存到BeanDefinition

  2. 之后就是触发实例化前的修改逻辑,内部可以将Bean中使用占位符形式填充的属性换成真正的属性值。

  3. 下一步将实例化后的处理逻辑先保存到容器中,在实例化之后直接触发即可。

  4. 然后需要初始化一个事件广播器并将其保存到IOC容器中,当事件发生时由事件广播器通知事件监听器从而执行对应的操作。

  5. 之后就是事件监听器的实例化,将其保存到上一步中的事件广播器中,事件经过事件广播器的发布之后,对应的事件监听器就会得到通知

  6. 然后进行所有Bean的第一次实例化,在这一步加入了类型转换的服务,内部保存了很多的类型转换器,之后就是实例化所有的Bean

  7. 第一次实例化所有的Bean时,单例池中并没有需要的Bean,所以需要从头创建,首先创建一个空Bean,创建完成之后判断是不是FactoryBean类型的Bean,如果是的话需要从其中取出真正的Bean返回

  8. 将创建的空Bean的信息保存到三级缓存中,便于后期出现循环依赖时使用,而循环依赖中会提前尝试AOP,从而得到Bean的原始对象或者代理对象。这也导致后面正常的AOP过程不一定会触发

  9. 三级缓存中,每一级缓存的作用都不相同,大致区别如下:

    • 三级缓存:保存一个lambda表达式,调用其中的getObject方法就能获得一个尝试代理之前的对象,用来打破循环依赖
    • 二级缓存:用来保存尝试过代理后的Bean,保持Bean单例性
    • 一级缓存:保存实例化完成之后的Bean,便于复用,这里的Bean已经是完成
  10. 然后就是属性填充,有两种属性填充的方式,首先进行注解属性填充

  11. 然后进行普通的xml文件配置的属性填充

  12. 之后使用Aware回调机制实现容器资源的注入

  13. 之后执行初始化前的逻辑,主要是执行应用上下文的容器资源注入

  14. 初始化执行逻辑中主要是执行初始化方法,初始化方法有两种方式,一种实现对应的接口,一种是在xml文件中配置指定初始化方法的名称

  15. 初始化后的逻辑中进行正常AOP的操作,由于前面可能对Bean进行提前AOP,这里不一定触发

  16. 之后就是将销毁方法注册到钩子函数中,在容器销毁之前进行调用

  17. 经历上面的步骤之后,Bean创建完成,之后将单例Bean保存到单例池中

  18. 后期再使用时走到第7步时就先尝试从单例池中拿,拿不到才会重新创建

​ 以上的步骤只是精简过后描述的Bean的生命周期,细节需要查看提供的代码,代码在开发过程中参考了小傅哥的文章,从文章中受益匪浅。

About

🌼🌻🌷从零实现一个小型的spring框架,通过手写spring源码来理解spring中的重要知识点。主要包括IOC,资源感知注入,对外扩展,AOP,事件机制等内容。

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages