# 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篇分析每个方法的源码。
# 4、Spring
容器刷新的12个方法具体分析
- 1、Spring源码 – 容器刷新#prepareRefresh()
- 2、Spring源码 – 容器刷新#obtainFreshBeanFactory()
- 3、Spring源码 – 容器刷新#prepareBeanFactory()
- 4、Spring源码 – 容器刷新#postProcessBeanFactory()
- 5、Spring源码 – 容器刷新#invokeBeanFactoryPostProcessors()
- 6、Spring源码 – 容器刷新#registerBeanPostProcessors()
- 7、Spring源码 – 容器刷新#initMessageSource()
- 8、Spring源码 – 容器刷新#initApplicationEventMulticaster()
- 9、Spring源码 – 容器刷新#onRefresh()
- 10、Spring源码 – 容器刷新#registerListeners()
- 11、Spring源码 – 容器刷新#finishBeanFactoryInitialization()
- 12、Spring源码 – 容器刷新finishRefresh()
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13
备注:此文为笔者学习
Spring
源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。
今天的文章Spring源码 – 容器刷新分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/11795.html