SpringBean生命周期笔记

BeanPostProcessor执行步骤总结

BeanPostProcessor执行步骤总结或者说spring bean生命周期里的扩展点进行总结

public void createBean() {
    // 可以返回一个bean以中断后续的实例化操作
    1.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation();
    doCreateBean() {
        // 进行实例化
        createBeanInstance() {
            // 如果通过之前的方法都没能解析出构造函数,调用该后置处理方法获取构造器
            2.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors();
        }
        applyMergedBeanDefinitionPostProcessors() {
            // 使用构造器实例化完毕后,将merged Beandefinitiong暴露出来
            // 比如把被`@Autowired、@Value`等注解标记的成员变量或者方法实例标记
            // 方便后续`populateBean()进行依赖注入的时候使用
            3.MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition();
        }
        // 进行属性填充
        populateBean() {
            // 可用于自定义属性填充,短路后续属性填充逻辑
            4.InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation();
            // 细粒度的处理,@Autowired就在此处进行依赖注入
            5.InstantiationAwareBeanPostProcessor#postProcessProperties();
        }
        // 进行初始化
        initializeBean() {
            // 生命周期里的一些awareMethod
            invokeAwareMethods() {
                BeanNameAware#setBeanName();
                BeanClassLoaderAware().setBeanClassLoader();
                BeanFactoryAware.setBeanFactory();
            }
            6. BeanPostProcessor#postProcessBeforeInitialization();
            7. BeanPostProcessor#postProcessAfterInitialization();
        }
    }
}

public void destroyBean() {
    8. DestructionAwareBeanPostProcessor#postProcessBeforeDestruction();
}

------------------------下边是简单的源码分析--------------------

重点BeanPostProcessor类图

[图片上传失败...(image-a6ddf6-1618332360968)]
主要介绍四个接口

  • InstantiationAwareBeanPostProcessor
  • SmartInstantiationAwareBeanPostProcessor
  • MergedBeanDefinitionPostProcessor
  • DestructionAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor里边主要有三个方法

  • postProcessBeforeInstantiation
  • postProcessAfterInstantiation
  • postProcessProperties

主要作用于bean实例化的过程

postProcessBeforeInstantiation

@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    return null;
}

用来在对象实例化前直接返回一个对象,代替通过内置的实例化流程创建对象,如果该方法出现返回值,说明返回的Object为初始化好的对象,转而执行BeanPostProcessor#postProcessBeforeInitialization方法。

该方法在生命周期里执行时间参考AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]),在createBean()方法体里,doCreateBean()方法之前调用

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    .......
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    if (bean != null) {
        return bean;
    }
    ....,.
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    return beanInstance;
    ......
}


@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);               
            if (targetType != null) {
                // 执行postProcessBeforeInstantiation()
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 执行applyBeanPostProcessorsAfterInitialization()
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }           
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

postProcessAfterInstantiation

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    return true;
}

在属性实例化完毕,执行populateBean()进行属性填充之前执行,如果返回值为falsespring跳过属性填充及依赖注入的步骤。可以用于用户自定义属性填充操作。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
    ...... create bean instance.
    Object exposedObject = bean;
    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    ......
}

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    ...... 校验步骤
    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    // 在此处调用postProcessAfterInstantiation()方法
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 如果调用返回为false,中断后续的属性填充逻辑
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }
    ...... 属性填充逻辑   
}

postProcessProperties

@Nullable
default PropertyValues postProcessProperties(
        PropertyValues pvs, Objects bean, String beanName) throws BeansException {
    return null;
}

提供了更细粒度的操作,在spring处理完默认的成员属性,应用到指定的bean之前进行调用,可以用来进行属性检查和修改

@Autowired、@Resource等注解就是在这里实现最终的依赖注入

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
    ...... create bean instance.
    Object exposedObject = bean;
    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    ......
}

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    ......
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // (AutowiredAnnotationBeanPostprocessor实现了该方法对@Autowired标记的属性进行依赖注入)
            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;
        }
    }   
    ......  
}

SmartInstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor继承于InstantiationAwareBeanPostProcessor里边扩展了三个方法

  • predictBeanType
  • determineCandidateConstructors
  • getEarlyBeanReference

主要作用于bean实例化的过程

predictBeanType

default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
   return null;
}

调用时机不确定,如果beanDefinition中没有beanType,可以调用这个方法预测beanType

protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
   Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
   // Apply SmartInstantiationAwareBeanPostProcessors to predict the
   // eventual type after a before-instantiation shortcut.
   if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            Class<?> predicted = ibp.predictBeanType(targetType, beanName);
            if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
                  FactoryBean.class.isAssignableFrom(predicted))) {
               return predicted;
            }
         }
      }
   }
   return targetType;
}

determineCandidateConstructors

default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
   return null;
}

提供一个扩展点,来获取或者改变用来实例化的构造函数(比如没有通过bean定义构造器及参数的情况下,会根据这个扩展点确定构造器)

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
      ......
      instanceWrapper = createBeanInstance(beanName, mbd, args);
      ......
}

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   ......
       
   // Candidate constructors for autowiring?
   // 如果之前都没能够解析出构造器,调用createBeanInstance()尝试解析出构造器
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
   }
   ......
}

// 调用所有的#determineConstructorsFromBeanPostProcessors解析构造函数
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException {
   if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
            if (ctors != null) {
               return ctors;
            }
         }
      }
   }
   return null;
}

getEarlyBeanReference

default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
   return bean;
}

获取要提前暴露的bean的引用,用来支持单例bean的循环引用,在调用第三级缓存时,会调用getEarlyBeanReference()方法来获取实例。

我们都知道Spring解决单例的时候,使用了三级缓存

  • 第一级从已经初始化完成的singletonMap中获取
  • 第二级从earluSingletonMap中获取
  • 第三级从singletonFactoryMap中获取

从直觉上来说,使用earluSingletonMap已经可以解决循环依赖的问题,为什么还要有第三级ObjectFactory缓存存在呢?这是为了解决aop的问题,也是getEarlyBeanReference的关键。关于循环依赖的问题,不在这里进行分析。

MergedBeanDefinitionPostProcessor

提供唯一方法

  • postProcessMergedBeanDefinition

将merged BeanDefinition暴露出来

void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

在bean实例化完毕后调用,将merged BeanDefinition暴露出来,让使用者可以对其进行修改。比如其重点实现类AutowiredAnnotationBeanPostProcessor该类在此处把被@Autowired、@Value等注解标记的成员变量或者方法实例标记,方便后续populateBean()进行依赖注入的时候使用

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
      ......
      applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      ......   
}

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof MergedBeanDefinitionPostProcessor) {
         MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
         bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
      }
   }
}

DestructionAwareBeanPostProcessor

里边扩展方法

  • postProcessBeforeDestruction

用于在对象销毁时执行销毁前置逻辑,比如清除缓存、监控等功能的实现

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容