导读

Spring在Java Web方面有着举足轻重的地位,spring的源码设计更是被很多开发者所惊叹,巧妙的设计,精细的构思,都注定他的地位。今天陈某大言不惭的带你来从源码角度解析Spring的生命周期。

Spring中Bean的生命周期从容器的启动到停止,涉及到的源码主要是在AbstractApplicationContext.refresh方法中,下面也是围绕其中的逻辑进行讲解。

撸他

思路很简单,直接从refresh方法进入,一个方法一个方法的分析,搞死他。

【1】 prepareRefresh()

内部其实很简单,就是设置一些标志,比如开始时间,激活的状态等。

【2】prepareBeanFactory

做一些简单的准备工作,此处不再赘述!!!

【3】postProcessBeanFactory

主要的作用就是添加了一个后置处理器ServletContextAwareProcessor

【4】invokeBeanFactoryPostProcessors

调用容器中的所有的BeanFactoryPostProcessor中的postProcessBeanFactory方法,按照优先级调用,主要实现逻辑在invokeBeanFactoryPostProcessors()

(1) 执行所有BeanDefinitionRegistryPostProcessor的方法,同样是内部按照优先级进行排序调用。

(2) 对剩余的进行按照优先级排序调用,同样是内部进行排序执行。

【5】registerBeanPostProcessors

注册所有的BeanPostProcessor(后置处理器),按照优先级注册,分别是PriorityOrdered,Ordered,普通的,内部的。主要的实现逻辑在PostProcessorRegistrationDelegate.registerBeanPostProcessors()

【6】initMessageSource()

注册MessageSource,提供消息国际化等功能。

【7】initApplicationEventMulticaster()

注册事件广播器ApplicationEventMulticaster,用于spring事件的广播和事件监听器的处理。

【8】registerListeners()

注册事件监听器ApplicationListener,并且广播一些早期的事件,主要的逻辑在AbstractApplicationContext.registerListeners

【9】finishBeanFactoryInitialization

实例化所有非懒加载的Bean,spring生命周期中的主要方法,主要逻辑在DefaultListableBeanFactory.preInstantiateSingletons,深入进去其实就是getBean()方法创建,详情向下看。

【10】finishRefresh()

主要的功能是发布事件ContextRefreshedEvent

【11】destroyBeans()

容器启动出现异常时销毁Bean

以上就是Spring容器启动的过程,主要的逻辑都在AbstractApplicationContext#refresh中,其他的都很容易理解,现在我们着重分析一下单例Bean的创建过程,入口是第9步

创建Bean

1.实际主要的逻辑都在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()) {//如果是FactoryBeanif (isFactoryBean(beanName)) {//getBeanObject bean = getBean(FACTORY_BEAN_PREFIX + beanName);//非FactoryBean,getBeanelse {getBean(beanName);}}}

以上源码总结得知,最终实例化Bean的方法肯定在getBean中的,debug进入,得知doGetBean是大boss,spring源码有趣的是最终的实现都是在doxxxx()

【2】AbstractBeanFactory#doGetBean,由于篇幅太短,就不贴源码了,只贴关键代码

实例化的主要流程全部都在这里,下面一一解析即可。

(1) getSingleton(beanName)

从早期的缓存中获取,如果存在返回Bean,实例化

(2)getParentBeanFactory()

从父工厂的中获取Bean

(3)if (mbd.isSingleton())

分单例和多例进行分开创建Bean,这里只分析单例Bean的创建

(4)getSingleton(xx)

createBean方法创建Bean,进入createBean()

  1. resolveBeforeInstantiation(beanName, mbdToUse):

    执行所有的InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation,在实例化之前调用,返回null继续下一步,返回一个bean,那么bean实例化完成,将调用其中的postProcessAfterInstantiation方法

  2. doCreateBean(beanName, mbdToUse, args):创建Bean的完成过程

  3. 进入doCreateBean,createBeanInstance(beanName, mbd, args):创建Bean的实例

  4. populateBean():执行InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation,再执行postProcessProperties方法。

  5. initializeBean:初始化Bean,debug进入

  6. invokeAwareMethods:BeanNameAware,BeanClassLoaderAware,BeanFactoryAware中的对应方法。

  7. applyBeanPostProcessorsBeforeInitialization: BeanPostProcessord中的postProcessBeforeInitialization方法

  8. invokeInitMethods:执行InitializingBean中的afterPropertiesSetinit-method

  9. applyBeanPostProcessorsAfterInitialization:调用BeanPostProcessor中的postProcessAfterInitialization方法

总结

以上是spring容器从启动到销毁的全部过程,根据源码陈某画了一张生命周期的图,由于长度太长,不能展示出来,只能展示个缩略图了。想要的私聊我或者关注微信公众号,回复关键词【spring生命周期】。

往期精选

老司机带你手写shiro框架!!!

小白进阶架构师就差这套2T视频资源了!!!

SpringBoot多数据源切换,你会吗?

一文搞懂Spring AMQP

老司机带你从源码开始撸Spring生命周期!!!相关推荐

  1. 【vn.py学习笔记(六)】vn.py constant源码阅读、委托生命周期

    [vn.py学习笔记(六)]vn.py constant源码阅读.委托生命周期 写在前面 1 constant 1.1 Direction 1.2 Offset 1.3 Status 1.4 Prod ...

  2. 跟着小马哥学系列之 Spring IoC(源码篇:Bean 生命周期)

    跟着小马哥学系列之 Spring IoC(源码篇:Bean 生命周期) 简介 Bean 元信息来源 Bean 元信息解析成 BeanDefinition 并注册 BeanDefinition 转变成 ...

  3. Spring源码深度解析,Spring源码以及Bean的生命周期(五)(附代码示例:)

    五)Bean 的生命周期,创建---初始化---销毁的过程 目录 五)Bean 的生命周期,创建---初始化---销毁的过程 一 ,  指定初始化方法 init-method 方法​ 二 ,指定销毁 ...

  4. Spring源码分析——Bean的生命周期

    文章目录 说明 测试代码 说明 本文从源码的角度分析Spring中Bean的加载过程,本文使用的Spring版本为4.3.25.RELEASE 测试代码 测试代码如下,根据这段简单的测试代码,一步步跟 ...

  5. Spring源码分析-深入理解生命周期之BeanFactoryProcessor

    生命周期之BeanFactoryPostProcessor 先来看看bean的生命周期.对于熟悉spring 的朋友来说,bean的生命周期并不陌生.它可以在bean加载,bean初始化的过程中加入我 ...

  6. zuul源码分析之Request生命周期管理

    为什么80%的码农都做不了架构师?>>>    zuul核心框架 zuul是可以认为是一种API-Gateway.zuul的核心是一系列的filters, 其作用可以类比Servle ...

  7. vue源码解析:vue生命周期方法$destory方法的实现原理

    我们知道vue生命周期的最后一个阶段是销毁阶段,那么vue会调用自己的destory函数,那么$destory函数的实现原理是什么?且往下看. 用法: vm.$destroy() 作用: 完全销毁一个 ...

  8. PHP源码分析-PHP的生命周期

    PHP的最多的两种运行模式是WEB模式.CLI模式. 无论哪种模式,PHP工作原理都是一样的,作为一种SAPI运行. 1.当我们在终端敲入php这个命令的时候,它使用的是CLI. 它就像一个web服务 ...

  9. Vue源码之 Vue的生命周期

    天地初开就是new Vue(options),里面就一句话 this._init(options); (Vue.prototype.init 的赋值在initMixin(Vue)方法里) _init方 ...

最新文章

  1. 终止线程的2种方法。标记法和中断
  2. java 依赖算法_java – Maven 2 – 从传递依赖版本定义依赖版本
  3. .net 新添加的项目未加载_JDK 13 新特性一览
  4. 服务降级及dubbo中的实现示例
  5. mysql分析表_MySQL分析表有什么用
  6. nuc8 黑苹果_萝莉的身材野兽的心——NUC8 MacOS黑苹果-Win10双系统体验
  7. suse linux vnc 桌面号,在SUSE Linux下安装VNC的方法
  8. js 终止 for 循环
  9. hi3798mv300救砖包_迪优美特V26_hi3798mv300线刷固件升级包纯净系统
  10. js中继承的几种方式
  11. html前端小技巧—div半透明设置技巧
  12. 常用的人格测试理论等小结
  13. linux xorg占用显存过大
  14. Linux企业运维篇——git+gitlab+jenkins+docker构成持续集成环境
  15. EuroSys'14 会议记录
  16. java spring boot jms_spring boot整合JMS(ActiveMQ实现)
  17. buu [SWPU2019]ReverseMe1 wp
  18. jquery 获取某个值得键名_jquery中获取元素里某一特定子元素的代码
  19. STM32H743使用QSPI驱动W25Q128JV芯片(正点原子例程修改)
  20. aix mysql启动_aix mysql | 学步园

热门文章

  1. 把EXCEL表格导入到MYSQL中_将EXCEL表格中的数据导入mysql数据库表中(两种方法)...
  2. 计算机网络七年级教学设计,初中七年级信息技术《计算机网络和因特网》教学设计.docx...
  3. 学完教程,不知道接下去从哪里开始做自己的第一个APP,怎么办?酷课堂iOS交流群问答(201902期)
  4. 魔镜魔镜告诉我谁是世界上最美的人 语音唤醒,百度语音识别。从装系统开始
  5. 网易音乐网站系统|前后端分离springboot+vue实现在线音乐网站
  6. 2015-10-17
  7. 蓝牙耳机选哪个?盘点双十二必入的高性价比蓝牙耳机
  8. (32)【文件下载漏洞专题】Filedownload原理、漏洞出现、危害、漏洞利用……
  9. Simscape物理网络建模的基本原理
  10. 2014年电大计算机应用基础考,2014年中央电大计算机应用基础网考最新修改版小抄.doc...