导读

  • 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):调用BeanNameAwareBeanClassLoaderAwareBeanFactoryAware中的对应方法

​ g. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName):调用BeanPostProcessord中的postProcessBeforeInitialization方法

​ h. invokeInitMethods(beanName, wrappedBean, mbd):执行InitializingBean中的afterPropertiesSet

​ i. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName):调用BeanPostProcessor中的postProcessAfterInitialization方法

总结

以上是spring容器从启动到销毁的全部过程,根据源码陈某画了一张生命周期的图,仅供参考,请勿转载!!!

  • 如果觉得作者写的好,有所收获的话,点个关注推荐一下哟!!!

Spring生命周期详解的更多相关文章

  1. ASP.NT运行原理和页面生命周期详解及其应用

    ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用.  ...

  2. ASP.NET生命周期详解

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  3. ASP.NET生命周期详解 [转]

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  4. ASP.NET生命周期详解(转)

    看到好文章需要分享. 最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多 ...

  5. React—组件生命周期详解

    React—组件生命周期详解 转自 明明的博客  http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...

  6. Spring bean的生命周期详解

    bean的生命周期1.实例化bean 即new2.按照spring上下文对实例化的bean进行配置 即填充属性,也就是IOC/DI(控制反转,依赖注入)3.如果这个bean实现了BeanNameAwa ...

  7. Spring之Bean的生命周期详解

      通过前面多个接口的介绍了解了Bean对象生命周期相关的方法,本文就将这些接口的方法串起来,来了解Bean的完整的生命周期.而介绍Bean的生命周期也是面试过程中经常会碰到的一个问题,如果不注意就跳 ...

  8. Spring Bean生命周期详解

    对象生命周期:创建(实例化----初始化)---使用----销毁,而在Spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化.初始化.销毁) ...

  9. Spring Bean的生命周期详解(转)

    Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...

随机推荐

  1. A Knight's Journey (DFS)

    题目: Background The knight is getting bored of seeing the same black and white squares again and agai ...

  2. 测试LFI WITH PHPINO过程中的一些记录

    原理:以往LFI漏洞都是需要满足两个条件:1.攻击者上传一个含PHP代码的的文件,后缀名任意,没有后缀名也可以:2.需要知道上传后的文件路径及文件名,然后包含之. 后来有国外研究者发现了新的攻击方式, ...

  3. Python——用turtle模块画海龟的第一步

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  4. ZYNQ自定义AXI总线IP应用——PWM实现呼吸灯效果

    一.前言 在实时性要求较高的场合中,CPU软件执行的方式显然不能满足需求,这时需要硬件逻辑实现部分功能.要想使自定义IP核被CPU访问,就必须带有总线接口.ZYNQ采用AXI BUS实现PS和PL之间 ...

  5. Spring的工作原理

    一.什么是Spring (1).Spring真正的精华是它的Ioc模式实现的BeanFactory和AOP,它自己在这个基础上延伸的功能有些画蛇添足. (2). Spring它是一个开源的项目,而且目 ...

  6. node--非阻塞式I/O,单线程,异步,事件驱动

    1.单线程 不同于其他的后盾语言,node是单线程的,大大节约服务器开支 node不为每个客户创建一个新的线程,仅使用一个线程.通过非阻塞I/O以及 事件驱动机制,使其宏观上看是并发的,可以处理高并发 ...

  7. Qt_QChart的使用记录(小白)

    主要是记录柱状图的数值显示,散点图的点坐标显示(防止后续忘记,把文件都贴出来,方便复查) 资源库: WarehouseInputOrOutput.pro QT += core gui QT += ch ...

  8. 使用contenteditable+div模拟textarea文本域实现高度自适应

    使用contenteditable+div模拟textarea文本域实现高度自适应 开发过程中由于需要在发送消息的时候需要有一个可以高度自适应的文本域,一开始是使用textarea并搭配auto-si ...

  9. 编程老司机带你玩转 CompletableFuture 异步编程

    本文从实例出发,介绍 CompletableFuture 基本用法.不过讲的再多,不如亲自上手练习一下.所以建议各位小伙伴看完,上机练习一把,快速掌握 CompletableFuture. 个人博文地 ...

  10. Rust入坑指南:智能指针

    在了解了Rust中的所有权.所有权借用.生命周期这些概念后,相信各位坑友对Rust已经有了比较深刻的认识了,今天又是一个连环坑,我们一起来把智能指针刨出来,一探究竟. 智能指针是Rust中一种特殊的数 ...