Spring生命周期详解
导读
- Spring中Bean的生命周期从容器的启动到停止,涉及到的源码主要是在
org.springframework.context.support.AbstractApplicationContext.refresh
方法中,下面也是围绕其中的逻辑进行讲解。
开撸
【1】 prepareRefresh()
内部其实很简单,就是设置一些标志,比如开始时间,激活的状态等。
【2】prepareBeanFactory(beanFactory)
做一些简单的准备工作,此处不再赘述!!!
【3】postProcessBeanFactory(beanFactory)
主要的作用就是添加了一个后置处理器ServletContextAwareProcessor
【4】invokeBeanFactoryPostProcessors(beanFactory)
调用容器中的所有的BeanFactoryPostProcessor中的postProcessBeanFactory方法,按照优先级调用,主要实现逻辑在org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
(1) 执行所有BeanDefinitionRegistryPostProcessor(对BeanFactoryPostProcessor的扩展,运行在普通的实现类之前注册bean)的方法,同样是内部按照优先级进行排序调用
(2) 对剩余的进行按照优先级排序调用,同样是内部进行排序执行
【5】registerBeanPostProcessors(beanFactory)
注册所有的BeanPostProcessor(后置处理器),按照优先级注册,分别是PriorityOrdered,Ordered,普通的,内部的。主要的实现逻辑在PostProcessorRegistrationDelegate.registerBeanPostProcessors()
【6】initMessageSource()
注册MessageSource,提供消息国际化等功能
【7】initApplicationEventMulticaster();
注册事件广播器ApplicationEventMulticaster,用于spring事件的广播和事件监听器的处理
【8】registerListeners()
注册事件监听器ApplicationListener,并且广播一些早期的事件,主要的逻辑在org.springframework.context.support.AbstractApplicationContext.registerListeners
【9】finishBeanFactoryInitialization(beanFactory)
实例化所有非懒加载的Bean,spring生命周期中的主要方法,主要逻辑在org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons,深入进去其实就是getBean()方法创建,详情向下看。
【10】finishRefresh()
主要的功能是发布事件ContextRefreshedEvent
【11】destroyBeans()
容器启动出现异常时销毁Bean
以上就是Spring容器启动的过程,主要的逻辑都在org.springframework.context.support.AbstractApplicationContext#refresh中,其他的都很容易理解,现在我们着重分析一下单例Bean的创建过程,入口是第9步。
实例化单例Bean
【1】debug进入,实际主要的逻辑都在org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons方法中,逻辑如下:
//获取所有注入到ioc容器中的bean定义信息
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//循环创建
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//非抽象,单例,非懒加载的bean初始化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是FactoryBean
if (isFactoryBean(beanName)) {
//getBean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//非FactoryBean,getBean
else {
getBean(beanName);
}
}
}
以上源码总结得知,最终实例化Bean的方法肯定在getBean中的,debug进入,得知doGetBean是大boss,spring源码有趣的是最终的实现都是在doxxxx()。
【2】AbstractBeanFactory#doGetBean,由于篇幅太短,就不贴源码了,只贴关键代码
实例化的主要流程全部都在这里,下面一一解析即可。
(1) Object sharedInstance = getSingleton(beanName)
从早期的缓存中获取,如果存在返回Bean,实例化
(2)BeanFactory parentBeanFactory = getParentBeanFactory()
从父工厂的中获取Bean
(3)if (mbd.isSingleton())
分单例和多例进行分开创建Bean,这里只分析单例Bean的创建
(4)sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); }
createBean方法创建Bean,进入createBean()
a. Object bean = resolveBeforeInstantiation(beanName, mbdToUse):执行所有的InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation,在实例化之前调用,返回null继续下一步,返回一个bean,那么bean实例化完成,将调用其中的postProcessAfterInstantiation方法
b. Object beanInstance = doCreateBean(beanName, mbdToUse, args):创建Bean的完成过程
c. 进入doCreateBean,instanceWrapper = createBeanInstance(beanName, mbd, args):创建Bean的实例
d. populateBean(beanName, mbd, instanceWrapper):属性装配,执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,再执行postProcessProperties方法。
e. exposedObject = initializeBean(beanName, exposedObject, mbd):初始化Bean,debug进入
f. invokeAwareMethods(beanName, bean):调用BeanNameAware,BeanClassLoaderAware,BeanFactoryAware中的对应方法
g. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName):调用BeanPostProcessord中的postProcessBeforeInitialization方法
h. invokeInitMethods(beanName, wrappedBean, mbd):执行InitializingBean中的afterPropertiesSet
i. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName):调用BeanPostProcessor中的postProcessAfterInitialization方法
总结
以上是spring容器从启动到销毁的全部过程,根据源码陈某画了一张生命周期的图,仅供参考,请勿转载!!!
- 如果觉得作者写的好,有所收获的话,点个关注推荐一下哟!!!
Spring生命周期详解的更多相关文章
- ASP.NT运行原理和页面生命周期详解及其应用
ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用. ...
- ASP.NET生命周期详解
最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...
- ASP.NET生命周期详解 [转]
最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...
- ASP.NET生命周期详解(转)
看到好文章需要分享. 最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多 ...
- React—组件生命周期详解
React—组件生命周期详解 转自 明明的博客 http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...
- Spring bean的生命周期详解
bean的生命周期1.实例化bean 即new2.按照spring上下文对实例化的bean进行配置 即填充属性,也就是IOC/DI(控制反转,依赖注入)3.如果这个bean实现了BeanNameAwa ...
- Spring之Bean的生命周期详解
通过前面多个接口的介绍了解了Bean对象生命周期相关的方法,本文就将这些接口的方法串起来,来了解Bean的完整的生命周期.而介绍Bean的生命周期也是面试过程中经常会碰到的一个问题,如果不注意就跳 ...
- Spring Bean生命周期详解
对象生命周期:创建(实例化----初始化)---使用----销毁,而在Spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化.初始化.销毁) ...
- Spring Bean的生命周期详解(转)
Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...
随机推荐
- centos7 开机/etc/rc.local 不执行的问题(转载)
最近发现centos7 的/etc/rc.local不会开机执行,于是认真看了下/etc/rc.local文件内容的就发现了问题的原因了 #!/bin/bash # THIS FILE IS ADDE ...
- Hibernate之cascade属性和inverse属性
1.cascade属性 cascade属性的作用是描述关联对象进行操作时的级联特性,只有涉及关系的元素才有cascade属性.具有cascade属性的标记包括<many-to-one/>. ...
- tomcat启动后access error[730048]的解决方法
安装了JDK... 配置了系统变量... 解压了tomcat... 配置了系统变量... 点击startup.bat启动了以后,打开浏览器,出现access error 404错误. 仔细看过控制台输 ...
- 杂谈php之什么是cgi,fastcgi,fpm,cli,mod
杂谈PHP极少关注的问题 本话题来自于我使用PHP进行网页爬虫的一次经历.对于一个web开发者来说,PHP解释器本身却知之甚小,实在是惭愧呐! 首先这个话题要从几个提问开始. PHP是什么? 外文名: ...
- 企业级rancher搭建Kubernetes(采用rancher管理平台搭建k8s)
一.简介 Rancher简介 来源官方:https://www.cnrancher.com/ Rancher是一个开源的企业级容器管理平台.通过Rancher,企业再也不必自己使用一系列的开源软件去从 ...
- 設定MacOS 終端機環境 (Homebrew/zsh/oh-my-zsh/iTerm2)
安裝Homebrew 1 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/in ...
- Vue.js——学习笔记(一)
Vue-自学笔记 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅 ...
- 压力测试(六)-阿里云Linux服务器压测接口实战
1.SpringBoot 接口打包,并用jar包方式部署 简介:用jar包方式在控制台进行启动 打包 mvn package && java -jar target/gs-spring ...
- 配置VSCode的C/C++语言功能
0. 前言 主要是在网上找的方法都没试成功过,在各种机缘巧合下终于成功了. 这篇文章基于个人经验,而且没有走寻常路. 1. 需要的软件和插件 软件: VSCode (https://code.visu ...
- 《自拍教程36》段位三_Python面向对象类
函数只能面向过程,来回互相调用后顺序执行, 简单的编码项目,还能应付的过来, 复杂的大型项目,调用多了,就会乱. 如何才能不乱呢,可尝试下, 面向对象类的概念, 将现实世界的事物抽象成对象,将现实世界 ...