Spring Bean的生命周期——Create Bean源码解析

1. 前言:

在Spring的AbstractAutowireCapableBeanFactory中,方法繁多,但它们的功能可以大致归类为以下几个主要类别:

1. Bean工厂配置方法

这一类方法用于配置BeanFactory的行为。它们允许设置实例化策略、是否允许循环引用、参数名称发现器等。主要包括:

  • setInstantiationStrategy()
  • setParameterNameDiscoverer()
  • setAllowCircularReferences()
  • setAllowRawInjectionDespiteWrapping()
  • ignoreDependencyType()
  • ignoreDependencyInterface()
  • copyConfigurationFrom()

2. Bean创建和实例化方法

这些方法负责Bean的创建、实例化过程。它们处理从Bean定义到Bean实例化的整个过程,包括依赖注入、生命周期回调等。主要包括:

  • createBean()
  • autowireBean()
  • configureBean()
  • createBeanInstance()
  • doCreateBean()

3. 依赖处理方法

这一类方法用于处理Bean之间的依赖,包括自动装配和依赖查找。它们确保了Bean的依赖能被正确解析和注入。主要包括:

  • resolveDependency()
  • autowireBeanProperties()
  • populateBean()

4. Bean初始化和销毁方法

这些方法涉及到Bean生命周期的管理,包括初始化前后的处理、自定义初始化方法的调用,以及销毁方法的调用。主要包括:

  • initializeBean()
  • invokeInitMethods()
  • destroyBean()

5. 类型转换和Bean后处理器调用

此类别方法处理类型转换和Bean后处理器的调用,这对于Spring的数据绑定和扩展非常重要。主要包括:

  • applyBeanPostProcessorsBeforeInitialization()
  • applyBeanPostProcessorsAfterInitialization()

6. 工具和辅助方法

这一类方法提供了各种工具和辅助功能,如日志记录、异常处理、解析Bean名称、处理工厂Bean等。主要包括:

  • getBeanPostProcessors()
  • resolveBeanByName()
  • applyMergedBeanDefinitionPostProcessors()

每个类别的方法协同工作,共同支撑了Spring框架的IoC容器功能,实现了依赖注入、Bean的生命周期管理等核心特性。

2. 流程分析:

2.1 大致流程

sheel 复制代码
getBean(name)
    |
    V
doGetBean()
    |
    V
createBean()
    |
    V
resolveBeforeInstantiation(beanName, mbd) -----> Bean存在? -----> Yes -----> 结束
    |                                                                |
    No                                                               |
    |                                                                |
    V                                                                |
doCreateBean() ------------------------------------------------------
    |
    |---> createBeanInstance()  // 实例化Bean
    |       |
    |       V
    |    populateBean()       // 依赖注入
    |       |
    |       V
    |    initializeBean()     // 初始化Bean
    |       |
    |       |---> applyBeanPostProcessorsBeforeInitialization()
    |       |       |
    |       |       V
    |       |    invokeInitMethods()     // 调用自定义初始化方法
    |       |       |
    |       |       V
    |       |    applyBeanPostProcessorsAfterInitialization()
    |       |
    |       V
    |    registerDisposableBeanIfNecessary() // 注册销毁回调
    |
    V
结束

2.2 流程方法说明

2.2.1. 创建前检查createBean

  1. 这里主要是一些bean的准备工作,解析类的信息,日志之类的东西
  2. 值得注意是 bean 的前置处理,如果返回了bean的代理对象(aop),则会跳过下面的正常创建流程。
java 复制代码
 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Creating instance of bean '" + beanName + "'");
        }

        RootBeanDefinition mbdToUse = mbd;
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);

            try {
                mbdToUse.prepareMethodOverrides();
            } catch (BeanDefinitionValidationException var9) {
                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
            }
        }

        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var10) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
        }

        try {
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Finished creating instance of bean '" + beanName + "'");
            }

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            throw var7;
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
        }
    }

如果没有创建代理对象则跳转到doCreateBean() 创建对象

2.2.2. 检查缓存

factoryBeanInstanceCache是一个专门用来缓存FactoryBean创建的bean实例的缓存,而不是通常提到的处理循环依赖的一级、二级或三级缓存。

java 复制代码
BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

spring bean默认是单例模式,如果是单例模式的话,清除工厂缓存中的早期引用。

2.2.3. 实例化Bean

通过createBeanInstance(beanName, mbd, args);方法创建实例

java 复制代码
if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }
java 复制代码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        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());
        } else {
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return this.obtainFromSupplier(instanceSupplier, beanName, mbd);
            } else if (mbd.getFactoryMethodName() != null) {
                return this.instantiateUsingFactoryMethod(beanName, mbd, args);
            } else {
                boolean resolved = false;
                boolean autowireNecessary = false;
                if (args == null) {
                    synchronized(mbd.constructorArgumentLock) {
                        if (mbd.resolvedConstructorOrFactoryMethod != null) {
                            resolved = true;
                            autowireNecessary = mbd.constructorArgumentsResolved;
                        }
                    }
                }

                if (resolved) {
                    return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
                } else {
                    Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                        ctors = mbd.getPreferredConstructors();
                        return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
                    } else {
                        return this.autowireConstructor(beanName, mbd, ctors, args);
                    }
                }
            }
        }
    }
  1. 通过Supplier创建Bean实例
  • 如果Bean定义指定了一个Supplier来提供Bean的实例,则直接调用Supplier.get()方法来创建Bean实例。这是一个Java 8引入的功能,允许以编程方式控制Bean的实例化过程。
  1. 通过工厂方法创建Bean实例
  • 如果Bean定义指定了工厂方法(factoryMethodName不为null),则使用该工厂方法来创建Bean实例。这涉及到查找并调用相应的静态或实例级工厂方法。
  1. 自动装配构造器创建Bean实例
  • 如果Bean定义没有指定工厂方法,方法会尝试通过构造器自动装配来创建Bean实例。这个过程可能包括:
    • 检查是否已经解析了构造器或工厂方法及其参数(用于快速实例化)。
    • 如果没有解析过,或者传入了显式的构造器参数args,则尝试通过BeanPostProcessors推断合适的构造器(determineConstructorsFromBeanPostProcessors),或者使用Bean定义中指定的"首选"构造器。
  1. 直接实例化Bean
  • 如果没有指定工厂方法,也没有找到适用的构造器,那么会尝试直接使用无参构造器来实例化Bean(如果可能的话)。
  1. 返回BeanWrapper包装的实例

2.2.3. 设置Bean的类型

java 复制代码
Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

如果存储bean 类型的元数据

2.2.4. Bean定义的后处理

java 复制代码
synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.markAsPostProcessed();
            }
        }

在Bean实例化后、属性填充前,执行Bean定义的后处理器。

2.2.5. 处理循环依赖

java 复制代码
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }

            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

在单例模式,允许循环依赖,且bean可能正在创建(说明被循环依赖),如果存在互相引用,添加一个能够生成Bean早期引用的工厂对象到单例对象的缓存中。

2.2.6. 属性填充且初始化

java 复制代码
try {
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException bce) {
                if (beanName.equals(bce.getBeanName())) {
                    throw bce;
                }
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, var18.getMessage(), var18);
        }
  1. 初始化方法
java 复制代码
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        this.invokeAwareMethods(beanName, bean);
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, var6.getMessage(), var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
  1. 调用Aware接口方法
java 复制代码
this.invokeAwareMethods(beanName, bean);
  • 这一步主要是为了调用实现了Aware接口的bean的相应方法,让bean能够访问Spring容器的某些部分,比如BeanNameAware, BeanFactoryAware, ApplicationContextAware等。这样bean就可以获取到它的名称、所属的BeanFactory或者ApplicationContext。
  1. 应用前置处理器
java 复制代码
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean,beanName);
  • 在bean的初始化方法被调用之前,这一步会遍历并调用已注册的所有BeanPostProcessorpostProcessBeforeInitialization方法。这给了开发者一个机会在bean属性设置完成后、自定义初始化之前对bean实例进行额外的处理,比如检查或修改bean的属性。

3 调用初始化方法

java 复制代码
this.invokeInitMethods(beanName, wrappedBean, mbd);
  • 这一步负责调用bean的初始化方法。如果bean实现了InitializingBean接口,将会调用其afterPropertiesSet方法。此外,如果在bean定义中通过init-method属性指定了自定义的初始化方法,也会在这里被调用。
  1. 应用后置处理器
java 复制代码
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  • 在bean的初始化方法被调用之后,这一步会遍历并调用已注册的所有BeanPostProcessorpostProcessAfterInitialization方法。这为开发者提供了另一个机会在bean完全初始化之后对其进行额外的处理,比如创建代理来增强bean的功能。

2.2.7. 处理早期的bean引用实例

这一步的核心是,循环依赖早期暴露的bean和现在完全初始化后的一致,就ok,如果不一致,就都别运行了。

java 复制代码
if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }

                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

2.2.8. 返回经过处理的bean

java 复制代码
try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
相关推荐
尘浮生3 分钟前
Java项目实战II基于SpringBoot的共享单车管理系统开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·微信小程序·小程序
2401_857439698 分钟前
社团管理新工具:SpringBoot框架
java·spring boot·后端
ThetaarSofVenice19 分钟前
Java从入门到放弃 之 泛型
java·开发语言
嘟嘟Listing27 分钟前
jenkins docker记录
java·运维·jenkins
WHabcwu33 分钟前
统⼀异常处理
java·开发语言
zaim133 分钟前
计算机的错误计算(一百六十三)
java·c++·python·matlab·错数·等价算式
枫叶丹434 分钟前
【在Linux世界中追寻伟大的One Piece】多线程(一)
java·linux·运维
2401_8543910835 分钟前
Spring Boot OA:企业数字化转型的利器
java·spring boot·后端
山山而川粤42 分钟前
废品买卖回收管理系统|Java|SSM|Vue| 前后端分离
java·开发语言·后端·学习·mysql
武昌库里写JAVA44 分钟前
Vue3与Vue2 对比
spring boot·spring·毕业设计·layui·课程设计