首页IT科技bean生命周期简单总结(Bean的生命周期)

bean生命周期简单总结(Bean的生命周期)

时间2025-09-16 05:24:11分类IT科技浏览5026
导读:之前简单记录了下springBean的生命周期,最近翻开来看了下,发现自己遗漏了很多细节,很多点都衔接不上 今天重新翻看《spring揭秘》,查资料,补了许多细节。希望能够让自己和大家更容易看懂吧...

之前简单记录了下springBean的生命周期               ,最近翻开来看了下                      ,发现自己遗漏了很多细节        ,很多点都衔接不上 今天重新翻看《spring揭秘》            ,查资料                      ,补了许多细节               。希望能够让自己和大家更容易看懂吧

Bean的生命周期的完全实现需要两个阶段

容器的启动

bean的实例化过程(涵盖了bean生命周期的大部分)

容器的完全实现

bean实例化过程

容器启动阶段

重点是收集到元信息配置信息            ,即创建bean需要的信息(beanDefinition) 通过

BeanDefinitionReader,读取到

beanDefinition信息        ,再通过

beanDefinitionRegistry,将BeanDefinition注册到其里面

// 这是 PropertiesBeanDefinitionReader 把从properties文件读取到的配置信息                      ,// 通过 BeanDefinitionRegistry 注册 BeanDefinition的过程   AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(     parent, className, getBeanClassLoader());   bd.setScope(scope); // 作用域 默认singleton   bd.setAbstract(isAbstract); // 是否是抽象 默认false 如果是抽象的                ,容器不会实例化bean    ,而是将beanDefinition信息作为其子类使用   bd.setLazyInit(lazyInit); // 懒加载 默认false 如果是false,容器一启动就会加载bean   bd.setConstructorArgumentValues(cas); // 构造参数   bd.setPropertyValues(pvs); // 属性信息   getRegistry().registerBeanDefinition(beanName, bd); // 注册Beandefinition

BeanDefinitionReader 有多种,包括:

PropertiesBeanDefinitionReader 读取Properties配置文件

GroovyBeanDefinitionReader 读取Groovy配置文件

XmlBeanDefinitionReader 读取Xml配置文件

bean实例化前 对beanDefinition做出自定义修改

BeanFactoryPostProcessor实例化bean之前                      ,可以允许修改beanDefinition信息                    ,下面是spring默认实现的BeanFactoryPostProcessor类:

PropertyPlaceholderConfigurer允许我们在XML配置文件中使用占位符(PlaceHolder),并将这些占位符所代表的资源单独配置到简单的properties文件中来加载

PropertyOverrideConfigurer覆盖对象的属性值

我们可以自己实现

BeanFactoryPostProcessor依赖注入

beanFactory                   ,修改

beanDefinition信息

bean实例化阶段

doCreateBean源码方法(下面仅对beanFactory容器做解析                       ,applicationContext容器其实大同小异)

/**  * Actually create the specified bean. Pre-creation processing has already happened  * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.  * <p>Differentiates between default bean instantiation, use of a  * factory method, and autowiring a constructor.  * @param beanName the name of the bean  * @param mbd the merged bean definition for the bean  * @param args explicit arguments to use for constructor or factory method invocation  * @return a new instance of the bean  * @throws BeanCreationException if the bean could not be created  * @see #instantiateBean  * @see #instantiateUsingFactoryMethod  * @see #autowireConstructor  */ protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)   throws BeanCreationException {  // Instantiate the bean.  BeanWrapper instanceWrapper = null;  if (mbd.isSingleton()) {   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  }  if (instanceWrapper == null) {   instanceWrapper = createBeanInstance(beanName, mbd, args);  }        // 实例化bean  Object bean = instanceWrapper.getWrappedInstance();  Class<?> beanType = instanceWrapper.getWrappedClass();  if (beanType != NullBean.class) {   mbd.resolvedTargetType = beanType;  }  // Allow post-processors to modify the merged bean definition.  synchronized (mbd.postProcessingLock) {   if (!mbd.postProcessed) {    try {     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);    }    catch (Throwable ex) {     throw new BeanCreationException(mbd.getResourceDescription(), beanName,       "Post-processing of merged bean definition failed", ex);    }    mbd.postProcessed = true;   }  }  // Eagerly cache singletons to be able to resolve circular references  // even when triggered by lifecycle interfaces like BeanFactoryAware.  boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&    isSingletonCurrentlyInCreation(beanName));  if (earlySingletonExposure) {   if (logger.isTraceEnabled()) {    logger.trace("Eagerly caching bean " + beanName +      " to allow for resolving potential circular references");   }   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  }  // Initialize the bean instance.        Object exposedObject = bean;  try {                        // 填充bean对象属性   populateBean(beanName, mbd, instanceWrapper);                        //  初始化bean   exposedObject = initializeBean(beanName, exposedObject, mbd);  }  catch (Throwable ex) {   if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {    throw (BeanCreationException) ex;   }   else {    throw new BeanCreationException(      mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);   }  }  if (earlySingletonExposure) {   Object earlySingletonReference = getSingleton(beanName, false);   if (earlySingletonReference != null) {    if (exposedObject == bean) {     exposedObject = earlySingletonReference;    }    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {     String[] dependentBeans = getDependentBeans(beanName);     Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);     for (String dependentBean : dependentBeans) {      if (!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.");     }    }   }  }  // Register bean as disposable.  try {            // 检查是否实现DisposableBean接口    ,有的话注册销毁回调方法   registerDisposableBeanIfNecessary(beanName, bean, mbd);  }  catch (BeanDefinitionValidationException ex) {   throw new BeanCreationException(     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);  }  return

 exposedObject; } 首先第一步               ,调用

createBeanInstance方法                      ,利用反射调用类的构造方法        ,实例化bean            ,返回

beanWrapper对象,再调用

getWrappedInstance方法得到实例化的bean                      ,

beanWrapper对象具有获取对象属性的功能            ,所以可以调用

populateBean用来实现属性填充                      。

20230225155458

开始实例化bean之前        ,会检查bean有没有实现过

Aware接口                      ,如果有则实现        。

// AbstractAutowireCapableBeanFactory类中的 initializeBean方法private void invokeAwareMethods(String beanName, Object bean) {  if (bean instanceof Aware) {   // 如果Spring容器检测到当前对象实例实现了该接口                ,会将该对象实例的bean定义对应的beanName设置到当前对象实例            。   if (bean instanceof BeanNameAware) {    ((BeanNameAware) bean).setBeanName(beanName);   }   // 如果容器检测到当前对象实例实现了该接口    ,会将对应加载当前bean的Classloader注入当前对象实例                      。   // 默认会使用加载org.springframework.util.ClassUtils类的Classloader   if (bean instanceof BeanClassLoaderAware) {    ClassLoader bcl = getBeanClassLoader();    if (bcl != null) {     ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);    }   }   if (bean instanceof BeanFactoryAware) {    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);   }   // 以上几个Aware接口只是针对BeanFactory类型的容器而言  } }

对于ApplicationContext类型容器                      ,会额外实现几个Aware接口

BeanPostProcessor阶段

BeanPostProcessor的概念容易与BeanFactoryPostProcessor的概念混淆            。 但只要记住BeanPostProcessor是存在于对象实例化阶段                    ,而BeanFactoryPostProcessor则是存在于容器启动阶段,这两个概念就比较容易区分了        。

BeanPostProcessor 有两个需要子类实现的方法

public interface BeanPostProcessor { /**  * 调用bean的init方法之前做的前置处理  */ @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  return bean; } /**  * 调用bean的init方法之后做的前置处理  */ @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  return bean; }}

在initializeBean方法内可以看到BeanPostProcessor的调用顺序

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {  if (System.getSecurityManager() != null) {   AccessController.doPrivileged((PrivilegedAction<Object>) () -> {    invokeAwareMethods(beanName, bean);    return null;   }, getAccessControlContext());  }  else {   // 调用实现了Aware接口的对象方法   invokeAwareMethods(beanName, bean);  }  Object wrappedBean = bean;  if (mbd == null || !mbd.isSynthetic()) {   // BeanPostProcessor前置处理   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  }  try {   // 调用bean的init方法   invokeInitMethods(beanName, wrappedBean, mbd);  }  catch (Throwable ex) {   throw new BeanCreationException(     (mbd != null ? mbd.getResourceDescription() : null),     beanName, "Invocation of init method failed", ex);  }  if (mbd == null || !mbd.isSynthetic()) {   // BeanPostProcessor后置处理   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  }  return wrappedBean; }

注意:applcationContext容器中实现BeanPostProcessor接口的postProcessBeforeInitialization中                  ,会对实现了Aware接口的bean进行invoke调用                      。 这里和BeanFactory有些不同                       ,BeanFactory是在BeanPostProcessor之前实现的

InitializingBean和init-method

这两个方法都是在invokeInitMethods方法里调用    , InitializingBean接口需要实现afterPropertiesSet 方法允许bean实例在设置完所有bean属性后执行其整体配置验证和最终初始化                。 init-method, 对于用户来说可以自定义方法的名称               ,也可以统一设置所有对象的initMethod比较灵活                      ,避免修改代码        ,耦合性低    。

DisposableBean与destroy-method

DisposableBean接口            ,子类需要实现destroy方法                      ,来销毁对象,只适用于单例对象            ,不是单例的话        ,需要交给调用者自己销毁                      。 destroy-method注册销毁函数                      ,作用和destroy方法同理

总结

本文主要讲了bean在BeanFacotry容器的生命周期                ,applicationContext容器稍微提了几点不同    ,applicationContext容器增加更多的特性                      ,像事件发布监听                    ,国际化信息支持等                    。 bean的生命周期主要涉及到容器的加载和bean的实例化。

容器的加载:

加载资源文件到beanDefinition(元信息)

调用实现了BeanFactoryPostProcessor接口的方法,可以对beanDefinition进行修改                  。

bean的实例化:

利用反射+beanDefinition元信息实例化得到对象

populateBean方法填充属性

检验对象是否实现过Aware接口                  ,有则调用其实现

如果对象有实现BeanPostProcessor接口                       ,需要先实现前置方法

调用InitializingBean和init-method方法 如果有实现或标记的话

再调用BeanPostProcessor接口的后置方法

最后查看对象是否实现 DisposableBean与destroy-method 来销毁bean(DisposableBean接口只针对单例bean)

资料:

《spring揭秘》王福强

本文由 mdnice 多平台发布

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
网上赚钱2020(网上赚钱项目有哪些-网络上月入几万的赚钱项目有吗?我来分享几个给你!)