• 【Spring源码系列】Bean生命周期-实例化前


    前言

    Bean的生命周期中,‘实例化前’操作是借助InstantiationAwareBeanPostProcessor接口实现的。

    一、实例化前 - InstantiationAwareBeanPostProcessor介绍

    BeanPostProcessor 提供的两个方法是:初始化前初始化后
    很多类实现BeanPostProcessor,且基于BeanPostProcessor类做了些扩展,比如InstantiationAwareBeanPostProcessor类,在此基础上扩展了实例化前实例化后属性填充

    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    
    	@Nullable
    	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    		return null;
    	}
    
    	
    	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    		return true;
    	}
    
    	
    	@Nullable
    	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    			throws BeansException {
    
    		return null;
    	}
    
    
    	@Deprecated
    	@Nullable
    	default PropertyValues postProcessPropertyValues(
    			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
    
    		return pvs;
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    InstantiationAwareBeanPostProcessor实例化前作用

    实例化前操作只做一件事情:遍历bean执行postProcessBeforeInstantiation方法

    InstantiationAwareBeanPostProcessor实例化前代码案例

    代码实现InstantiationAwareBeanPostProcessor接口:

    @Component
    public class UserBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
    	@Override
    	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    		// 声明:如果不指定对哪个bean进行处理,默认是对All的bean都会处理。
    		if ("userService".equals(beanName)) {
    			System.out.println("实例化前");
    		}
    		return null;
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    实现InstantiationAwareBeanPostProcessor接口关键点声明:
    1、 必须被@Component注解修饰。保证实现InstantiationAwareBeanPostProcessor接口的类可以被Spring扫描,扫描之后会被记录到BeanPostProcessorCache-instantiationAware属性集合中,目的是在创建每个bean的时候都会遍历instantiationAware集合执行postProcessBeforeInstantiation方法。
    2、实现InstantiationAwareBeanPostProcessor接口且重写postProcessBeforeInstantiation方法

    二、实例化前 - 源码分析

    声明关键点

    在讲源码之前呢,我们可以先增强几个知识点的概念。这些知识点在阅读’Spring-实例化前‘ 源码中起着关键作用。

    1、实例化前操作只做一件事情:遍历bean执行postProcessBeforeInstantiation方法
    2、Spring规定每一个BeanDefinition会执行‘实例化前’方法
    3、如果实例化前返回一个不为null的对象,下一步则直接到初始化后。postProcessBeforeInstantiation方法如果返回一个不为null的对象,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。
    4、AbstractBeanFactory$BeanPostProcessorCache类的instantiationAware集合在‘初始化前’就已经有值(**Spring容器启动的时候赋值的**)。不仅仅是instantiationAware,其余三个集合在执行‘初始化前’都已经被赋值。

    static class BeanPostProcessorCache {
    
    		/**
    		 * 下面四个均是BeanPostProcessor的子类;
    		 *
    		 */
    		final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();
    
    		final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();
    
    		final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();
    
    		final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    源代码解读

    我们先找到Spring调用‘实例化前’的具体代码位置,‘实例化前’栈调用轨迹如下:
    在这里插入图片描述org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]):

    // 实例化前
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    
    • 1
    • 2

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation:

    	@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.
    			// synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理
    			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    				Class<?> targetType = determineTargetType(beanName, mbd);
    				if (targetType != null) {
    					// 真正调用'实例化前'方法的地方。
    					// 此处会获取postProcessBeforeInstantiation返回的对象,如果对象不为null则直接执行'初始化后'。
    					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    					if (bean != null) {
    						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    					}
    				}
    			}
    			mbd.beforeInstantiationResolved = (bean != null);
    		}
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation:

    	@Nullable
    	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    		// getBeanPostProcessorCache()返回BeanPostProcessorCache对象,该对象的四个集合属性在执行'实例化前'就已经有值
    		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    			// 调用'实例化前-方法'
    			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
    			if (result != null) {
    				return result;
    			}
    		}
    		return null;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    org.springframework.beans.factory.support.AbstractBeanFactory#getBeanPostProcessorCache:

    BeanPostProcessorCache getBeanPostProcessorCache() {
    		// '初始化前'调用之前,beanPostProcessorCache就已经有值
    		BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
    		if (bpCache == null) {
    			bpCache = new BeanPostProcessorCache();
    			for (BeanPostProcessor bp : this.beanPostProcessors) {
    				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    					bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
    					if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
    						bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
    					}
    				}
    				if (bp instanceof DestructionAwareBeanPostProcessor) {
    					bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
    				}
    				if (bp instanceof MergedBeanDefinitionPostProcessor) {
    					bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
    				}
    			}
    			this.beanPostProcessorCache = bpCache;
    		}
    		return bpCache;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    95- 后程序员一出校门就拿年薪 -30 多万?,android 开发文档百度云
    从特斯拉林某某事件看Transformer
    基于redis集群的分布式锁redlock
    part-02 C++知识总结(类型转换)
    【JavaScript 20】String对象 构造函数 工具方法 静态方法 实例属性 实例方法
    直播预告 | 构建业务智联,快速拥抱财务数字化转型
    2023.10.17
    如何编写一份完整的软件测试报告?
    数据库管理-第四十六期 一些...疑惑吧~(20221203)
    Tesla_T4加速卡详细参数
  • 原文地址:https://blog.csdn.net/qq_43783527/article/details/128160635