本系列文章主要来讲解 Spring 框架 的实现原理以及如何进行扩展使用。
Spring 的加载方式
Spring 的加载方式有两种: ClassPathXmlApplicationContext
和 AnnotationApplicationContext
两种方式。两种方式的区别,只在 refresh()
之前存在不同。
ClassPathXmlApplicationContext 的加载方式
- 创建一个实体类
package com.recluse
public class Hello {
private String str;
// 省略 get / set 方法
}
- 创建 applicationContext.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用Spring来创建对象,在Spring这些都称为Bean
类型 变量名 = new 类型();
Hello hello = new Hello();
id = 变量名
class = new 的对象;
property 相当于给对象中的属性设置一个值!
-->
<bean id="hello" class="com.recluse.Hello">
<property name="str" value="mySpring"/>
</bean>
</beans>
- 创建 Spring 应用程序的上下文
public static void main (String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml")
Hello hello = context.getBean("str");
}
Spring 的加载过程
- 调用父类的构造方法,创建
PathMathingResourcePatternResolver
并解析配置文件 - 设置配置文件路径到当前应用程序中
- 开始进入容器的创建和刷新环节
refresh()
,这一步ClassPathXmlApplicationContext
和AnnotationApplicationContext
大体是相同的。
refresh 的处理过程
refresh 方法是由 12 个方法组成的,下面先对 12 个方法做一个简单的阐述,在之后的文章中会进行详细的说明
- prepareRefresh(): 容器刷新前的准备工作,其中包括记录容器的启动状态、终止状态、启动时间等等
- obtainFreshBeanFactory(): 创建容器,并且完成配置文件的加载,创建
DefaultListableBeanFactory
以及完成BeanDefination
的加载和解析工作 - prepareBeanFactory(beanFactory): 通过
add,set,ignore,register
给容器对象完成属性的赋值操作 - postProcessBeanFactory(beanFactory): 默认没有实现,留给子类进行实现操作
- invokeBeanFactoryPostProcessors(beanFactory): 执行 BFPP 接口中的方法
- registerBeanPostProcessors(beanFactroy): 注册 BeanPostProcessor, 完成 Spring 自带或者用户自定义的BeanPostProcessor的解析
- initMessageSource(): 初始化信息资源, 进行国际化相关的操作。MessageSource、Locale
- initApplicationEventMulticaster(): 初始化事件广播器
- onRefresh() 在 Spring 中默认没有任何实现, Springboot 启动了 web 容器
- registerListeners(): 注册监听器,接收广播的事件, 与 8 呼应
- finishBeanFactoryInitialization(beanFactory): 完成所有非懒加载的单例对象的实例化操作,
从此方法开始进行对象的创建,包含了实例化,初始化,循环依赖,AOP等核心逻辑的处理过程,此步骤是最最核心且关键的点,要对其中的细节最够清楚
- finishRefresh(): 完成刷新
Spring 全流程图
大家可以先根据图对整个流程中各个方法的工作内容有个大概的了解,之后会根据该流程图一点点的梳理整个 Spring 框架。