Spring Bean生命周期

本文内容纲要:

- 前言

- Spring Bean生命周期

- 源码分析

- 总结

前言

Spring Bean生命周期是常见的面试题,也是日常开发中经常用到的技术点,在应用开发中,常常需要执行一些特殊的初始化工作,如建立数据库连接,打开网络连接,又比如在一些业务bean里,你想拿到Spring IOC容器,又或者是想拿到一些已经实例化的Bean。同时,在服务结束时,也有一些销毁销毁工作需要执行。为了便于工作的设计,Spring IOC提供相关接口,可以让应用定制Bean的初始化和销毁。

Spring Bean生命周期

先来看一下Spring Bean生命周期流程图,方便对照后续的源码分析。


Spring Bean生命周期从大的节点上分为4个过程:实例化、属性赋值、初始化、销毁。 日常业务开发过程中,我们应该涉及最多的两个点就是初始化和销毁,比如自定义Bean实现InitializingBean、DisposeableBean。

源码分析

Spring IOC容器初始化

初始化从AbstractAutowireCapableBeanFactory.doCreateBean方法开始说起,我在对应的代码位置标注了关键点

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);

}

//1. Bean实例化

if (instanceWrapper == null) {

instanceWrapper = this.createBeanInstance(beanName, mbd, args);

}

Object bean = instanceWrapper.getWrappedInstance();

Class<?> beanType = instanceWrapper.getWrappedClass();

if (beanType != NullBean.class) {

mbd.resolvedTargetType = beanType;

}

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.postProcessed = true;

}

}

boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);

if (earlySingletonExposure) {

this.addSingletonFactory(beanName, () -> {

return this.getEarlyBeanReference(beanName, mbd, bean);

});

}

Object exposedObject = bean;

try {

//2.属性赋值

this.populateBean(beanName, mbd, instanceWrapper);

//3.初始化

exposedObject = this.initializeBean(beanName, exposedObject, mbd);

} catch (Throwable var18) {

if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {

throw (BeanCreationException)var18;

}

throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);

}

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 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");

}

}

}

}

try {

//4.销毁 - 注册回调接口

this.registerDisposableBeanIfNecessary(beanName, bean, mbd);

return exposedObject;

} catch (BeanDefinitionValidationException var16) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);

}

}

为了保持代码片段精简,我删掉了其中的logger代码。

从以上代码片段里可以看到我们上面总结的Spring生命后期4个关键点都有体现,我们着重分析初始化和销毁流程。

AbstractAutowireCapableBeanFactory.initializeBean

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

//1.检查Aware相关接口并设置相关依赖

//BeanNameAware, BeanClassLoaderAware, BeanFactoryAware

if (System.getSecurityManager() != null) {

AccessController.doPrivileged(() -> {

this.invokeAwareMethods(beanName, bean);

return null;

}, this.getAccessControlContext());

} else {

this.invokeAwareMethods(beanName, bean);

}

//2.BeanPostProcessor前置处理

Object wrappedBean = bean;

if (mbd == null || !mbd.isSynthetic()) {

//BeanPostProcessor接口的postProcessBeforeInitialization回调

wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);

}

//3.若实现InitializingBean接口,则调用afterPropertiesSet()

//4.若配置自定义的init-method(), 则执行。

try {

this.invokeInitMethods(beanName, wrappedBean, mbd);

} catch (Throwable var6) {

throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);

}

//5.BeanPostProcessor后置处理

if (mbd == null || !mbd.isSynthetic()) {

//BeanPostProcessor接口的postProcessAfterInitialization回调

wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

}

return wrappedBean;

}

AbstractAutowireCapableBeanFactory.invokeAwareMethods

invokeAwareMethod就是调用一系列Aware结尾的接口,比如

BeanNameAware、ApplicationContextAware、BeanFactoryAware。

private void invokeAwareMethods(String beanName, Object bean) {

if (bean instanceof Aware) {

if (bean instanceof BeanNameAware) {

((BeanNameAware)bean).setBeanName(beanName);

}

if (bean instanceof BeanClassLoaderAware) {

ClassLoader bcl = this.getBeanClassLoader();

if (bcl != null) {

((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);

}

}

if (bean instanceof BeanFactoryAware) {

((BeanFactoryAware)bean).setBeanFactory(this);

}

}

}

AbstractAutowireCapableBeanFactory.invokeInitMethods

invokeinitMethods就是调用InitializingBean接口的afterPropertiesSet,并且检查自定义init-method。

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {

boolean isInitializingBean = bean instanceof InitializingBean;

if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {

if (System.getSecurityManager() != null) {

try {

AccessController.doPrivileged(() -> {

((InitializingBean)bean).afterPropertiesSet();

return null;

}, this.getAccessControlContext());

} catch (PrivilegedActionException var6) {

throw var6.getException();

}

} else {

((InitializingBean)bean).afterPropertiesSet();

}

}

if (mbd != null && bean.getClass() != NullBean.class) {

String initMethodName = mbd.getInitMethodName();

if (StringUtils.hasLength(initMethodName) && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {

this.invokeCustomInitMethod(beanName, bean, mbd);

}

}

}

从以上代码片段可以看出Spring IOC容器创建Bean的过程, 涉及的过程包括实例化,销毁,还包括BeanPostProcessor接口相关方法实现,以上代码片段我们分析了Spring容器初始化过程加载Bean的各种实现,下面我们看下Spring容器销毁阶段。

容器销毁

Spring容器销毁过程调用链


Spring在这里用了适配器模式,也就是说最终的销毁任务由DisposableBeanAdapter来完成,我们看下DisposeableBeanAdapter的结构。


从结构中可以看到bean属性类型为Object, 也就是要销毁的Bean,还有beanName属性。

public void destroy() {

if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {

Iterator var1 = this.beanPostProcessors.iterator();

while(var1.hasNext()) {

DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor)var1.next();

processor.postProcessBeforeDestruction(this.bean, this.beanName);

}

}

if (this.invokeDisposableBean) {

try {

if (System.getSecurityManager() != null) {

AccessController.doPrivileged(() -> {

((DisposableBean)this.bean).destroy();

return null;

}, this.acc);

} else {

((DisposableBean)this.bean).destroy();

}

} catch (Throwable var3) {

}

}

if (this.destroyMethod != null) {

this.invokeCustomDestroyMethod(this.destroyMethod);

} else if (this.destroyMethodName != null) {

Method methodToInvoke = this.determineDestroyMethod(this.destroyMethodName);

if (methodToInvoke != null) {

this.invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));

}

}

}

总结

Spring Bean生命周期分为4个阶段和多个扩展点,扩展点又分为影响多个Bean和单个Bean。

4个阶段:实例化、属性赋值、初始化、销毁。

扩展点

影响多个Bean

  • BeanPostProcessor
  • InstantiationAwareBeanPostProcessor

影响单个Bean

  • BeanNameAware
  • BeanFactoryAware
  • BeanClassLoaderAware
  • ApplicationContextAware

Spring生命周期中两个关键的接口:InitializingBean, DisposableBean。

本文内容总结:前言,Spring Bean生命周期,源码分析,总结,

原文链接:https://www.cnblogs.com/sword-successful/p/14770835.html

以上是 Spring Bean生命周期 的全部内容, 来源链接: utcz.com/z/362475.html

回到顶部