前言
Spring是spring生态圈的基石,大家工作中常用的SSM框架,SpringBoot框架都是在Spring基础上衍生的,所以想更好的了解它们深入学习Spring是必不可少的。本章以综述的方式带大家快速了解Spring核心流程。
一:Spring源码核心结构
1.1 图示
1.2 Spring框架基本使用方式
XML配置文件 使用函数
由上述Spring的使用过程可以衍生出两个问题: 1. XML配置文件加载解析到容器中并实例化成Bean对象的主要步骤是什么? 2. IOC容器是以什么数据结构存储Bean对象的? 接下来我们就来探讨以上这两个问题。
二:配置文件的信息如何加载并解析成IOC容器
2.1 大致流程
2.2 Bean定义信息的定义方式
相信大家通过观察上图很容易就发现出问题,难道Bean的定义信息只能通过XML配置文件来定义吗?显然不是。Spring为了提高拓展性提供了一个Bean定义信息的接口,只要想承载Bean定义信息的只需要实现这个规范即可。
如图所示:
2.3 BeanDefinition对象
BeanDefinition对象就是BeanDefinitionReader在解析Bean定义信息时,将Bean的定义信息封装成的对象。例如将xml文件中的bean标签的内容封装成对象,从这个对象中我们可以获取所有bean标签中定义的信息,也可以修改配置文件中定义的信息。
看源码BeanDefinition的方法:
2.4 BeanDefinitionReader接口
这个接口是所有想要承载Bean定义信息所需要实现的接口,该接口定义了一系列的规范。
看BeanDefinitionReader的子实现类
2.5 从BeanDefinition对象实例化Bean对象
相信很多小伙伴们觉得有了BeanDefinition对象就可以直接实例化Bean对象,这种思想咋一看好像是对的,毕竟都有了Bean的定义信息直接按照Bean定义信息封装的对象BeanDefinition来实例化对象不就可以了吗?但是如果在程序运行过程中要动态改变Bean的信息怎么办?要随时改变Bean的信息怎么办?例如<property name=url value=${jdbc.url},在这个情况下是绝对不能直接将BeanDefinition实例化成Bean对象的,因为IOC容器并不认识 ${jdbc.url},所以我们要在对象真正实例化进入容器之前进行拦截,替换掉 ${jdbc.url}。
我们可以在Bean对象真正被实例化出来之前,加BeanFactoryPostProcessor,来达到动态修改Bean对象信息的目的。
2.6 自定义BeanFactoryPostProcessor的演示
输出结果图:
2.7 PlaceholderConfigurerSupport占位符配置支持
现在我们解决2.5提出的问题 ${jdbc_url}是怎么样被替换的呢?
源码截图:
2.8 对象实例化的方式
对象实例化的方式一般有两种,一种是直接new,一种是通过反射,那么spring在实例化bean对象的时候采用那种方式呢?
spring是通过反射来实例化bean对象的
1. new对象的方式只能通过默认构造方法或者用户自定义的构造方法来为对象属性初始化,而通过反射的方式
可以操作一个对象的所有属性,所有方法,所有注解,功能显得更加强大灵活,因此spring是通过反射来实
化bean对象的。
2.9 对象创建的流程
2.9.1 图示
2.9.2 填充属性
填充属性阶段会执行配置文件中property标签的内容,通过setter方法给对象的属性赋值。
注意:填充属性阶段是通过setter方法给属性赋值的,对象对应的属性必须有setter方法,否则property标签会失效。
2.9.3 执行int-method初始化方法
可以在类的成员方法中写一个初始化方法,在xml配置文件中的bean标签中指定该方法为init-method,那么在对象初始化的执行初始化方法阶段就会执行该方法。
示例
实体类 测试类 结果:
2.10 bean对象初始化阶段的细节分析
2.10.1 流程图
2.10.2 Aware接口
Aware接口是一个标记接口,顾名思义这个接口是感知的意思,即bean对象能够感知到所在的spring 容器对象。只要一个对象实现了Aware接口,并重写了setter方法,当这个对象交由spring容器创建的时候,spring容器会将自身的对象作为参数传入,这样我们就可以通过该bean对象的实例获取容器对象。
示例 实体类 测试类 结果 spring容器的Aware接口有很多,大家可以通过源码查看。
三:spring容器的存储结构
spring容器是以Map集合来存储bean对象的。 那么Map集合的key和value的类型有多少种呢?
3.1 string-object型
key为bean对象的id值,value为bean对象 相当于是以by-Name方式从容器中取出对象
3.2 class-object类型
key为bean对象的类信息,value为bean对象 相当于是以by-Type方式从容器中取出对象
3.3 string-objectFactory
key为bean对象的id值,value为生产bean对象的工厂
3.4 string-BeanDefinition
key为bean对象的id值,value为bean对象的定义信息。
四:总流程图
|