# Spring
源码 - 容器刷新
Spring版本:5.3.13-release
# 1、IOC(Inversion Of Control)
思想–控制反转
1、控制反转:
- 将对象创建与对象之间的调用过程,全权交给
Spring
进行管理。
2、使用IOC
的目的:
- 解耦
3、IOC
是一种思想,DI
就是对IOC
的一种实现方式:
-
DI(Dependency Injection)
依赖注入:容器能知道哪个组件(类)运行的时候,需要另外一个类(组件);容器通过反射的形式,将容器中准备好的的Bean
实例对象注入(利用反射给属性赋值)到实例中去。
只要是容器管理的组件,都能使用容器提供的强大功能。
# 2、Spring
中的IOC
接口
1、IOC
思想是基于IOC
容器完成,IOC
容器底层就是对象工厂。
2、Spring
提供IOC
容器实现的两种方式:
-
BeanFactory
接口:IOC
容器最基本的实现方式,是Spring
内部使用的接口,供Spring
内部使用。在加载配置文件的时候,不会去立即创建配置文件中配置的对象,而是在获取的或使用对象的时候创建对象。 -
ApplicationContext
接口:BeanFactory
的子接口,提供了比BeanFactory
更强大的功能。加载配置文件的时候就创建配置文件中声明的对象。在实际开发中,开发人员一般都是实现ApplicationContextAware
接口,通过ApplicationContext
去获取容器中的Bean
。
# 3、容器刷新AbstractApplicationContext#refresh()
Spring的容器刷新尤为重要,容器刷新的源码为AbstractApplicationContext#refresh()
。
AbstractApplicationContext#refresh()
源码:
@Override
public void refresh() throws BeansException, IllegalStateException {
// 进入同步代码块, 保证线程安全
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
// 准备刷新上下文环境。作用就是初始化一些状态和属性, 后后续的工作做准备
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 创建容器对象 : DefaultListableBeanFactory
// 加载 xml 配置文件或者配置类的属性到当前 beanFactory 中。最重要的就是 BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// beanFactory的准备工作。对各种属性进行填充
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 子类覆盖方法做额外处理, 此处我们自己一般不做任何扩展工作。默认没有实现。但是可以查看 web 中的代码, 是有具体实现的。
// 这个方法是模板方法设计模式的体验, 默认无任何实现, 预留给子类扩展使用
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// 调用各种 beanFactory 处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册 Bean 处理器。这里只是单纯的注册功能, 真正调用的是 getBean 方法
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
// 为上下文初始化 message 源, 即不同语言的消息体, 做国际化处理。
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件监听多路广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 预留给子类, 用于初始化其他的 Bean
onRefresh();
// Check for listener beans and register them.
// 在所有注册的 Bean 中查找 listener beans 并注册到消息消息广播中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化剩下的单实例 Bean(非惰性)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 完成容器刷新。通知生命周期处理器 lifecycle processor 刷新过程。同时发出 ContextRefreshEvent 告知别人容器已完成刷新。
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 防止 已经创建的 Bean 占用资源, 在异常处理中, 销毁在异常之前创建的单例 Bean
destroyBeans();
// Reset 'active' flag.
// 重置容器 active 标志为 false 状态
cancelRefresh(ex);
// Propagate exception to caller.
// 抛出异常
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
refresh()
中一共12个方法:
-
prepareRefresh()
: 准备刷新上下文环境。作用就是初始化一些状态和属性, 后后续的工作做准备。 -
obtainFreshBeanFactory()
:字面意思是获取新鲜的BeanFactory
,这里获取到的BeanFactory
是DefaultListableBeanFactory
。获取到BeanFactory
之后ApplicationContext
就具备了BeanFactory
的各项功能,可以对Bean
进行各种基础操作。 -
prepareBeanFactory()
:BeanFactory
的准备工作。对各种属性进行填充。 -
postProcessBeanFactory()
:对获取的BeanFactory
做后置增强处理,默认没有实现,子类覆盖方法做额外处理。但是在WEB
中这里是有具体实现的。模板方法设计模式。 -
invokeBeanFactoryPostProcessors()
:调用各种BeanFactory
增强处理器BeanFactoryPostProcessor
及其子接口BeanDefinitionRegistryPostProcessor
。注意,这里调用的各种BeanFactory
的增强处理器是在Bean
实例化之前。 -
registerBeanPostProcessors()
:注册BeanPostProcessor
处理器。这里只是单纯的注册功能, 真正调用的是getBean()
方法。 -
initMessageSource()
:为上下文初始化Message
源, 即不同语言的消息体做国际化处理。 -
initApplicationEventMulticaster()
:初始化事件监听多路广播器。 -
onRefresh()
:预留给子类, 用于初始化其他的 Bean。 -
registerListeners()
:在所有注册的Bean
中查找listener beans
并注册到消息消息广播中。 -
finishBeanFactoryInitialization()
:初始化剩下的单实例Bean
(非惰性)。 -
finishRefresh()
:完成容器刷新。通知生命周期处理器lifecycle processor
刷新过程。同时发出ContextRefreshEvent
告知别人容器已完成刷新。
由于这里总共有12个方法,源码篇幅较多,所以分为12篇分析每个方法的源码。
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13
备注:此文为笔者学习
Spring
源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。