Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

在网上已经有跟多Bean的生命周期的博客,但是很多都是基于比较老的版本了,最近吧整个流程化成了一个流程图。待会儿使用流程图,说明以及代码的形式来说明整个声明周期的流程。注意因为代码比较多,这里的流程图只画出了大概的流程,具体的可以深入代码

一、获取Bea

第一阶段获取Bean

这里的流程图的入口在 AbstractBeanFactory类的 doGetBean方法,这里可以配合前面的 getBean方法分析文章进行阅读。主要流程就是

1、先处理Bean 的名称,因为如果以“&”开头的Bean名称表示获取的是对应的FactoryBean对象;
2、从缓存中获取单例Bean,有则进一步判断这个Bean是不是在创建中,如果是的就等待创建完毕,否则直接返回这个Bean对象
3、如果不存在单例Bean缓存,则先进行循环依赖的解析
4、解析完毕之后先获取父类BeanFactory,获取到了则调用父类的getBean方法,不存在则先合并然后创建Bean

二、创建Bean

2.1 创建Bean之前

在真正创建Bean之前逻辑

这个流程图对应的代码在 AbstractAutowireCapableBeanFactory类的 createBean方法中。

1、这里会先获取 RootBeanDefinition对象中的Class对象并确保已经关联了要创建的Bean的Class 。整编:微信公众号,搜云库技术团队,ID:souyunku
2、这里会检查3个条件

(1)Bean的属性中的 beforeInstantiationResolved字段是否为true,默认是false。
(2)Bean是原生的Bean
(3)Bean的 hasInstantiationAwareBeanPostProcessors属性为true,这个属性在Spring准备刷新容器钱转杯BeanPostProcessors的时候会设置,如果当前Bean实现了 InstantiationAwareBeanPostProcessor则这个就会是true。

当三个条件都存在的时候,就会调用实现的 InstantiationAwareBeanPostProcessor接口的 postProcessBeforeInstantiation方法,然后获取返回的Bean,如果返回的Bean不是null还会调用实现的 BeanPostProcessor接口的 postProcessAfterInitialization方法,这里用代码说明

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
 Object bean = null;
 //条件1
 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
 //条件2跟条件3
 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 Class<?> targetType = determineTargetType(beanName, mbd);
 if (targetType != null) {
 //调用实现的postProcessBeforeInstantiation方法
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
 if (bean != null) {
//调用实现的postProcessAfterInitialization方法
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
 }
 }
 }
 //不满足2或者3的时候就会设置为false
            mbd.beforeInstantiationResolved = (bean != null);
 }
 return bean;
 }

1、如果上面3个条件其中一个不满足就不会调用实现的方法。默认这里都不会调用的这些 BeanPostProcessors的实现方法。然后继续执行后面的 doCreateBean方法。

2.1 真正的创建Bean,doCreateBean

doCreateBean方法逻辑

这个代码的实现还是在 AbstractAutowireCapableBeanFactory方法中。流程是

1、先检查 instanceWrapper变量是不是null,这里一般是null,除非当前正在创建的Bean在 factoryBeanInstanceCache中存在这个是保存还没创建完成的FactoryBean的集合。
2、调用createBeanInstance方法实例化Bean,这个方法在后面会讲解
3、如果当前 RootBeanDefinition对象还没有调用过实现了的 MergedBeanDefinitionPostProcessor接口的方法,则会进行调用 。整编:微信公众号,搜云库技术团队,ID:souyunku
4、 当满足以下三点
(1)是单例Bean
(2)尝试解析bean之间的循环引用
(3)bean目前正在创建中
则会进一步检查是否实现了 SmartInstantiationAwareBeanPostProcessor接口如果实现了则调用是实现的 getEarlyBeanReference方法 5、 调用 populateBean方法进行属性填充,这里后面会讲解 6、 调用 initializeBean方法对Bean进行初始化,这里后面会讲解

2.1.1 实例化Bean,createBeanInstance

实例化Bean

这里的逻辑稍微有一点复杂,这个流程图已经是简化过后的了。简要根据代码说明一下流程

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
 //步骤1
 Class<?> beanClass = resolveBeanClass(mbd, beanName);

 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 "Bean class isn‘t public, and non-public access not allowed: " + beanClass.getName());
 }
 //步骤2
 Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
 if (instanceSupplier != null) {
 return obtainFromSupplier(instanceSupplier, beanName);
 }
 //步骤3
 if (mbd.getFactoryMethodName() != null) {
 return instantiateUsingFactoryMethod(beanName, mbd, args);
 }

 boolean resolved = false;
 boolean autowireNecessary = false;
 if (args == null) {
 synchronized (mbd.constructorArgumentLock) {
 if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
 }
 }
 }
 //步骤4.1
 if (resolved) {

 if (autowireNecessary) {
 return autowireConstructor(beanName, mbd, null, null);
 }
 else {

 return instantiateBean(beanName, mbd);
 }
 }

 //步骤4.2
 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
 if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
 return autowireConstructor(beanName, mbd, ctors, args);
 }

 //步骤5
        ctors = mbd.getPreferredConstructors();
 if (ctors != null) {
 return autowireConstructor(beanName, mbd, ctors, null);
 }

 return instantiateBean(beanName, mbd);
 }

1、先检查Class是否已经关联了,并且对应的修饰符是否是public的
2、如果用户定义了Bean实例化的函数,则调用并返回
3、如果当前Bean实现了 FactoryBean接口则调用对应的 FactoryBean接口的 getObject方法
4、根据getBean时候是否传入构造参数进行处理
4.1 如果没有传入构造参数,则检查是否存在已经缓存的无参构造器,有则使用构造器直接创建,没有就会调用 instantiateBean方法先获取实例化的策略默认是 CglibSubclassingInstantiationStrategy,然后实例化Bean。最后返回
4.2 如果传入了构造参数,则会先检查是否实现了 SmartInstantiationAwareBeanPostProcessor接口,如果实现了会调用 determineCandidateConstructors获取返回的候选构造器。整编:微信公众号,搜云库技术团队,ID:souyunku
4.3 检查4个条件是否满足一个
(1)构造器不为null,
(2)从RootBeanDefinition中获取到的关联的注入方式是构造器注入(没有构造参数就是setter注入,有则是构造器注入)
(3)含有构造参数
(4)getBean方法传入构造参数不是空

满足其中一个则会调用返回的候选构造器实例化Bean并返回,如果都不满足,则会根据构造参数选则合适的有参构造器然后实例化Bean并返回

5、如果上面都没有合适的构造器,则直接使用无参构造器创建并返回Bean。

2.1.2 填充Bean,populateBean

填充Bean

这里还是根据代码来说一下流程

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
 if (bw == null) {
 if (mbd.hasPropertyValues()) {
 throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
 }
 else {
 // Skip property population phase for null instance.
 return;
 }
 }
 boolean continueWithPropertyPopulation = true;
 //步骤1
 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 for (BeanPostProcessor bp : getBeanPostProcessors()) {
 if (bp instanceof InstantiationAwareBeanPostProcessor) {
 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
 break;
 }
 }
 }
 }

 if (!continueWithPropertyPopulation) {
 return;
 }
//步骤2--------------------
 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

 int resolvedAutowireMode = mbd.getResolvedAutowireMode();
 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
 MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
 // Add property values based on autowire by name if applicable.
 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
 }
 // Add property values based on autowire by type if applicable.
 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
 }
            pvs = newPvs;
 }

 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

 PropertyDescriptor[] filteredPds = null;
//步骤3
 if (hasInstAwareBpps) {
 if (pvs == null) {
                pvs = mbd.getPropertyValues();
 }
 for (BeanPostProcessor bp : getBeanPostProcessors()) {
 if (bp instanceof InstantiationAwareBeanPostProcessor) {
 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
 if (pvsToUse == null) {
 if (filteredPds == null) {
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
 }
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
 if (pvsToUse == null) {
 return;
 }
 }
                    pvs = pvsToUse;
 }
 }
 }
 if (needsDepCheck) {
 if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
 }
            checkDependencies(beanName, mbd, filteredPds, pvs);
 }
//步骤4
 if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
 }
 }
 

1、检查当前Bean是否实现了 InstantiationAwareBeanPostProcessor的 postProcessAfterInstantiation方法则调用,并结束Bean的填充。
2、将按照类型跟按照名称注入的Bean分开,如果注入的Bean还没有实例化的这里会实例化,然后放到 PropertyValues对象中。
3、如果实现了 InstantiationAwareBeanPostProcessor类的 postProcessProperties则调用这个方法并获取返回值,如果返回值是null,则有可能是实现了过期的 postProcessPropertyValues方法,这里需要进一步调用 postProcessPropertyValues方法
4、进行参数填充

2.1.3 初始化Bean,initializeBean

初始化Bean

同时这里根据代码跟流程图来说明

1、如果Bean实现了 BeanNameAwareBeanClassLoaderAwareBeanFactoryAware则调用对应实现的方法 。整编:微信公众号,搜云库技术团队,ID:souyunku
2、Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor的 postProcessBeforeInitialization则会调用实现的 postProcessBeforeInitialization方法。在 ApplicationContextAwareProcessor类中实现了 postProcessBeforeInitialization方法。而这个类会在Spring刷新容器准备 beanFactory的时候会加进去,这里就会被调用,而调用里面会检查Bean是不是 EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAwareApplicationContextAware的实现类。这里就会调用对应的实现方法。代码如下

 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 .......
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
 .......
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
 return bean;
 }

 AccessControlContext acc = null;

 if (System.getSecurityManager() != null) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
 }

 if (acc != null) {
 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
 return null;
 }, acc);
 }
 else {
            invokeAwareInterfaces(bean);
 }

 return bean;
 }

1、实例化Bean然后,检查是否实现了 InitializingBean的 afterPropertiesSet方法,如果实现了就会调用
2、Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor的 postProcessBeforeInitialization则会调用实现的 postProcessAfterInitialization方法。

到此创建Bean 的流程就没了,剩下的就是容器销毁的时候的了

三、destory方法跟销毁Bean

Bean在创建完毕之后会检查用户是否指定了 destroyMethodName以及是否实现了 DestructionAwareBeanPostProcessor接口的 requiresDestruction方法,如果指定了会记录下来保存在 DisposableBeanAdapter对象中并保存在bean的 disposableBeans属性中。代码在 AbstractBeanFactory的 registerDisposableBeanIfNecessary

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
 ......
                registerDisposableBean(beanName,
 new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
 ......
 }
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
 List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
 .......
 String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
 if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
 !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
 ......
 this.destroyMethod = destroyMethod;
 }
 this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
 }
 

在销毁Bean的时候最后都会调用 AbstractAutowireCapableBeanFactory的 destroyBean方法。

 public void destroyBean(Object existingBean) {
 new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
 }

这里是创建一个 DisposableBeanAdapter对象,这个对象实现了Runnable接口,在实现的 run方法中会调用实现的 DisposableBean接口的 destroy方法。并且在创建 DisposableBeanAdapter对象的时候会根据传入的bean是否实现了 DisposableBean接口来设置 invokeDisposableBean变量,这个变量表实有没有实现 DisposableBean接口

 public DisposableBeanAdapter(Object bean, List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
 Assert.notNull(bean, "Disposable bean must not be null");
 this.bean = bean;
 this.beanName = bean.getClass().getName();
 //根据传入的bean是否实现了`DisposableBean`接口来设置`invokeDisposableBean`变量
 this.invokeDisposableBean = (this.bean instanceof DisposableBean);
 this.nonPublicAccessAllowed = true;
 this.acc = acc;
 this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
 }

 public void destroy() {
 ......
 //根据invokeDisposableBean决定是否调用destroy方法
 if (this.invokeDisposableBean) {
 if (logger.isTraceEnabled()) {
                logger.trace("Invoking destroy() on bean with name ‘" + this.beanName + "‘");
 }
 try {
 if (System.getSecurityManager() != null) {
 AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
 ((DisposableBean) this.bean).destroy();
 return null;
 }, this.acc);
 }
 else {
 ((DisposableBean) this.bean).destroy();
 }
 }
 catch (Throwable ex) {
 String msg = "Invocation of destroy method failed on bean with name ‘" + this.beanName + "‘";
 if (logger.isDebugEnabled()) {
                    logger.warn(msg, ex);
 }
 else {
                    logger.warn(msg + ": " + ex);
 }
 }
 }
......
 }

四、总结。

最后来一个大的流程

实例化前的准备阶段

实例化前

实例化后

初始化前

————————————————

本人免费整理了Java高级资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共30G,需要自己领取。
传送门:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ

原文地址:https://www.cnblogs.com/yunxi520/p/12104144.html

时间: 2024-11-03 22:50:06

Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析的相关文章

spring 中bean生命周期

从头开始学习spring(一) 传统编程中,依赖关系比较多的情况下,导致维护成本直线上升,spring 采用Ioc对bean进行管理,减少了开发人员的工作量 正确理解spring bean 的生命周期非常重要 package com.study.spring.beans; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org

spring中bean生命周期

一  bean指定初始化和销毁方法 1.bean的生命周期:bean的创建 ---> 初始化 ---> 销毁的过程   bean的生命周期有容器来管理   单例的bean在创建时执行初始化方法,在spring关闭时执行销毁方法   原型的bean在每次获取时执行初始化方法,没有销毁方法   我们可以自己指定初始化和销毁方法,要指定的方法必须是bean所属的类的方法.注意:这个方法必须是个无参的方法 2.创建实体类 public class Car { private String name;

一步步剖析spring bean生命周期

关于spring bean的生命周期,是深入学习spring的基础,也是难点,本篇文章将采用代码+图文结论的方式来阐述spring bean的生命周期, 本篇文章将阐述清楚下图. 一  项目结构及源码 1.程序目录结构 2.applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/sc

Spring点滴四:Spring Bean生命周期

Spring Bean 生命周期示意图: 了解Spring的生命周期非常重要,我们可以利用Spring机制来定制Bean的实例化过程. --------------------------------------------------------------------------------------------------------------------------------------------------- spring-service.xml: <?xml version=

【Spring学习】Bean生命周期

我理解的Bean生命周期包括两个方面: Bean何时创建,何时销毁 Bean从创建到销毁的执行流程 一.Bean创建与销毁 Bean的创建时机主要由几个配置项共同来决定,包括: scope属性,决定是Bean是单例模式(singleton)还是多例模式(prototype),默认为单例singleton: lazy-init属性,只对单例模式有效,决定是否延时加载,默认为false,表示在容器初始化时,就会生成单例: RequestMapping属性,这个注解MVC中才有,当有该属性时,lazy

Spring事务,Bean生命周期

一.事务相关: 1.Spring事务基于Spring AOP切面编程: 2.AOP基于代理模式,得到需要开启事务的代码的代理对象: 3.而没有开启事务的Service方法里调用了开启事务 @Transactional 的方法时,整个代码是不会开启事务的,原理还是代理模式插入事务的依据是最外层的注解: 4.对于上面3,反之,则可以,这是事务的传播机制. 二.Bean生命周期: 2.1生命周期图: 出自:<精通Spring 4.x> 2.2不同级别的接口分类: 1.Bean本身的方法:Bean的构

bean生命周期

那在spring中bean的生命周期究竟是怎样的呢 1. 容器寻找Bean的定义信息并将其实例化 2. 使用依赖注入,spring按照Bean定义信息配置Bean的所有属性 3. 如果Bean实现了BeanNameAware接口,工厂调用Bean的SetBeanName()方法传递Bean的ID 4. 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身 5. 如果BeanPostProcessor和Bean关联,那么其postProc

Bean 生命周期

对于普通的Java对象,当new的时候创建对象,当它没有任何引用的时候被垃圾回收机制回收.而由Spring IoC容器托管的对象,它们的生命周期完全由容器控制. Bean生命周期流程 1.实例化Bean 实例化Bean对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化. 对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean. 容器通过获取B

11张流程图帮你搞定 Spring Bean 生命周期

在网上已经有跟多Bean的生命周期的博客,但是很多都是基于比较老的版本了,最近吧整个流程化成了一个流程图.待会儿使用流程图,说明以及代码的形式来说明整个声明周期的流程.注意因为代码比较多,这里的流程图只画出了大概的流程,具体的可以深入代码 一.获取Bea 第一阶段获取Bean 这里的流程图的入口在 AbstractBeanFactory类的 doGetBean方法,这里可以配合前面的 getBean方法分析文章进行阅读.主要流程就是 1.先处理Bean 的名称,因为如果以“&”开头的Bean名称