栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring源码学习三——Bean的生命周期主流程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring源码学习三——Bean的生命周期主流程

文章目录
  • 一、实例化
    • 1.1 getBean
    • 1.2 createBean
  • 二、初始化
    • 2.1 populateBean
    • 2.2 Aware回调
    • 2.3 前置增强postProcessBeforeInitialization
      • 2.3.1 @PostConstruct
    • 2.4 执行初始化方法
      • 2.4.1 afterPropertiesSet
      • 2.4.2 init-method
    • 2.5 后置增强postProcessAfterInitialization
  • 三、销毁
    • 3.1 destroy
      • 3.1.1 @PreDestroy
      • 3.1.2 DisposableBean
      • 3.1.3 destroy-method
  • 四、总结

一、实例化

前文讲到容器启动方法refresh()里面,调用finishBeanFactoryInitialization()方法会实例化所有非懒加载的单例bean,bean的生命周期得入口就在这里
前面那些都不重要,进入红框中的方法

beanNames里面是BeanDefinition的名称,singletonObjects是单例池。比较一下还有一些我们自己创建的类未被实例化

如果一个bean不是抽象的、是单例的且不是懒加载就会进入if,然后如果这个bean是FactoryBean,会特殊处理,但最终都会进入getBean(),这里没有直接创建bean,而是先从缓存里面拿,如果没有就创建bean,进入getBean

1.1 getBean

进入doGetBean();spring里面带do的方法就是真正做事的。

getSingleton(beanName);第一次得到的肯定是空,往下跳过不重要的部分

进入getSingleton

这行调用了函数式接口的getObject()

继续进入,就回到了lambda表达式里面的createBean(),开始创建bean的实例

1.2 createBean

进入createBean之后一路往下到达doCreateBean,真正做事的方法

先进入createBeanInstance,往下走到instantiateBean

注释是说没有特殊处理:简单的使用无参构造方法

进入beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);

拿到无参构造器方法保存到BeanDefinition的resolvedConstructorOrFactoryMethod属性

最终调用newInstance得到了实例对象,其实就是用了反射机制生成对象

二、初始化


看注释,这里就是初始化开始的地方

2.1 populateBean

populateBean()方法就是属性注入,如果有依赖其他bean就会先完成其他bean的生命周期。这就可能会引发循环依赖,循环依赖的问题我在其他文章中有讲,这里就不详细说了,现在只关心主流程。

2.2 Aware回调

exposedObject = initializeBean(beanName, exposedObject, mbd);–>invokeAwareMethods(beanName, bean);

Aware的顺序是BeanNameAware–>BeanClassLoaderAware–>BeanFactoryAware

2.3 前置增强postProcessBeforeInitialization

返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);进入

这里执行了所有注册过的BeanPostProcessor的postProcessBeforeInitialization方法,用来处理指定的bean。

2.3.1 @PostConstruct

这里特别注意一下有个CommonAnnotationBeanPostProcessor的增强器,它的构造方法

会设置初始化注解PostConstruct,它的postProcessBeforeInitialization继承至InitDestroyAnnotationBeanPostProcessor

postProcessBeforeInitialization执行进入

findLifecycleMetadata(bean.getClass());–>buildLifecycleMetadata()

这里将@PostConstruct注解的方法加入到了currInitMethods是一个List,最终加入了LifecycleMetadata的initMethods
所以注解@PostConstruct多个方法都会被执行,继续看在哪里执行,回到postProcessBeforeInitialization,从metadata.invokeInitMethods(bean, beanName);进入

这里执行所有的初始化方法

2.4 执行初始化方法 2.4.1 afterPropertiesSet

返回到initializeBean方法从invokeInitMethods(beanName, wrappedBean, mbd);进入

先检查是否实现InitializingBean,如果有就执行afterPropertiesSet方法,继续往下

getInitMethodName()拿到的是手动指定的初始化方法,即xml文件配置bean时指定的init-method属性。之后执行init-method指定的方法

2.4.2 init-method

mbd.getInitMethodName()获取的是initMethodName,看看它在何时赋值

最终发现是在xml解析的时候赋值的


initMethodName类型是String,也就是说只能有一个init-method方法

2.5 后置增强postProcessAfterInitialization

返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
进入

执行所有的后置增强

三、销毁 3.1 destroy

在Spring容器关闭的时候,会去销毁所有的单例Bean

进入

close()–doClose();–>destroyBeans();–>super.destroySingletons();–> destroySingleton(disposableBeanNames[i]);–>super.destroySingleton(beanName);–>destroyBean(beanName, disposableBean);–>bean.destroy();

3.1.1 @PreDestroy

bean在销毁的时候会执行DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法

InitDestroyAnnotationBeanPostProcessor实现了DestructionAwareBeanPostProcessor,因此会执行它的postProcessBeforeDestruction,进而执行metadata.invokeDestroyMethods(bean, beanName);
前面讲过@PostConstruct,在那里同时处理的还有@PreDestroy注解。最终将@PreDestroy注解的方法名添加到了LifecycleMetadata.destroyMethods,而这些方法都将在这里一并执行

3.1.2 DisposableBean

如上图,如果bean实现了DisposableBean接口,会先执行它自己实现的destroy方法

3.1.3 destroy-method

最后会执行xml指定的destroy-method方法,与init-mehod类似。

这里的destroyMethodName就是来自xml指定的destroy-method

四、总结

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/859434.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号