1、背景
Spring作为Java Web开发使用最频繁的框架,具有非常高的学习价值,在Spring框架源码中包含了很多设计模式(单例、原型、代理、观察者等),读懂这些源码有助于拓宽开发思路,同时也能提高后端排查错误的能力。以下将从IOC、DI、AOP三个主要模块进行Spring框架剖析,同时尝试手写实现Spring的基础功能。
2、Spring模块分析和手写
IOC
什么是IOC?
IOC(Inversion of control)控制反转将对象的获取途径交给spring管理,是spring的核心。
IOC有什么好处?
- 简化代码,不需要去手动new常见的bean对象;
- 面向接口编程,便于内容扩展;
- 方便进行AOP编程;
IOC容器(Bean工厂)做了哪些工作?
负责创建和管理类实例,向使用者提供实例。
IOC容器又称为Bean工厂(工厂模式),使用者调用getBean()方法,工厂则查找相应的Bean定义,生成实例(返回Object对象)。
手写Spring IOC框架
整体设计思路
1、IOC容器本质上是一个bean工厂,主要实现bean的定义、创建和管理。因此我们需要先定义出Bean定义的模型,并把BeanDefinition交给BeanFactory,整体设计思路如图。
BeanDefinition
1、工厂的核心是创建bean对象,有三种方式:new、工厂成员方法、工厂静态方法,因此需要对外提供相应的接口
创建实例图
2、增强功能要求:
bean有作用域的区分(单例或原型),同时需要管理bean的生命周期(初始化、使用、销毁);
BeanFactory
1、BeanDefinition需要注册到BeanFactory中,该过程通过BeanDefinitionRegistry接口实现(注册+发现),并由BeanFactory实现类实现这些接口。
2、BeanFactory接口需要实现最基础的功能:获取bean,即getBean()方法;
3、所以,IOC中的默认bean工厂实现类(DefaultBeanFactory)包含以下功能:
(1)实现bean定义信息的注册;(registerBeanDefinition()方法实现,验证通过后放入beanDefinitionMap中)
(2)实现bean实例的创建;(通过构造器方法、静态工厂方法、工厂bean方法这三种方式的对象创建方式)
(3)实现初始化方法的执行;(通过doInit()方法实现)
(4)实现单例的要求;(可在系统启动时进行初始化,通过PreBuildBeanFactory子类实现)
(5)实现容器关闭是执行单例的销毁操作(通过close()方法实现)
最终逻辑对应类图如下:
4、增强功能:
- 给bean实例增加别名。允许多个别名,也可以有别名的别名(通过AliasRegistry接口中的方法实现针对别名的CRUD)。
图
- 增加更多获取bean实例的接口方法(除了根据beanName以外,还可以根据class类型来获取bean实例的Map/List集合)
图
(此时需要考虑建立type(class)与beanName之间的关系,需要建立一个一对多的Map集合)
-
最终类图如下:
DI
介绍
DI(Dependency injection)依赖注入,对象之间的依赖由IOC容器在运行期决定,即容器会动态地将某个依赖注入到对象中,也就是bean对象的成员变量赋值。
哪些地方会有依赖
- 构造参数依赖(构造方法)
- 属性依赖(getter和setter)
AOP分析
3、bean的生命周期
1、创建
2、使用
3、销毁