InstantiationAwareBeanPostProcessor 学习

简介

注意:我使用的是SpringBoot版本:2.5.3
在这里插入图片描述
BeanPostProcessor包括二个初始化相关方法,InstantiationAwareBeanPostProcessor:包括这个实例化相关方法,以及一个属性值相关方法,postProcessProperties(postProcessPropertyValues在此版本中被标记为过时
先整体看一下,这个五个方法执行的顺序,如流程图
在这里插入图片描述

测试例子

相关文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="com.szh.quartzx.User" id="user" init-method="start">
        <property name="name" value="波波烤鸭"></property>
    </bean>

    <bean class="com.szh.quartzx.MyInstantiationBeanPostProcessor"/>
</beans>

User 对象


public class User {

    private int id;

    private String name;

    private String beanName;


    public User(){
        System.out.println("执行了构造方法------》User 被实例化");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("开始设置属性喽:设置:"+name);
        this.name = name;
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }
    public void start(){
        System.out.println("自定义初始化的方法....");
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", beanName=" + beanName + "]";
    }
}

MyInstantiationBeanPostProcessor


public class MyInstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    // 初始化方法-before
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(">>postProcessBeforeInitialization---初始化方法--对象已经存在了");

        return bean;
    }


    // 初始化-after
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("<<postProcessAfterInitialization -- 在Bean的自定义初始化方法执行完成之后执行--对象已经存在");
        return bean;
    }

    /**
     * 在实例化之前调用,如果返回null,一切按照正常顺序执行,如果返回的是一个实例的对象,那么这个将会跳过实例化、初始化的过程
     * @param beanClass
     * @param beanName
     * @return
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("--->postProcessBeforeInstantiation ---在方法实例化之前执行  Bean对象还没有");
        // 利用cglib生成代理对象
        if (beanClass == User.class){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(beanClass);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//                    System.out.println("方法执行之前:"+method);
                    Object object = methodProxy.invokeSuper(o, objects);
//                    System.out.println("方法执行之后:+"+method);
                    return object;
                }
            });
            User user = (User) enhancer.create();
            // 返回代理类
            return user;
        }
        return null;
    }

    /**
     * 在实例化之后,postProcessBeforeInitialization之前执行
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("<---postProcessAfterInstantiation --在方法实例化之后执行  Bean对象已经创建出来了");
        return true;
    }

    /**
     * 实例化之后调用,属性填充之前
     * @param pvs PropertyValues对象,用于封装指定类的对象,简单来说就是PropertyValue的集合,里面相当于以key-value形式存放类的属性和值
     * @param pds PropertyDescriptor对象数组,PropertyDescriptor相当于存储类的属性,不过可以调用set,get方法设置和获取对应属性的值
     * @param bean 当前的bean
     * @param beanName beanName
     * @return 如果返回null,那么将不会进行后续的属性填充,比如依赖注入等,如果返回的pvs额外的添加了属性,那么后续会填充到该类对应的属性中。
     */
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
                                                    String beanName) throws BeansException {
        System.out.println("<---postProcessPropertyValues--可以用来修改Bean中属性的内容->");
        return pvs;
    }
}

测试类

    @Test
    public void test1() {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = ac.getBean(User.class);
        System.out.println(user);
        // 关闭销毁
        ac.registerShutdownHook();
    }

根据是否返回 BeforeInstant 是否返回null,有二种情况

// 返回null
--->postProcessBeforeInstantiation ---在方法实例化之前执行  Bean对象还没有
执行了构造方法------User 被实例化
<---postProcessAfterInstantiation --在方法实例化之后执行  Bean对象已经创建出来了
<---postProcessPropertyValues--可以用来修改Bean中属性的内容->
开始设置属性喽:设置:波波烤鸭
>>postProcessBeforeInitialization---初始化方法--对象已经存在了
自定义初始化的方法....
<<postProcessAfterInitialization --Bean的自定义初始化方法执行完成之后执行--对象已经存在
User [id=0, name=波波烤鸭, beanName=null]

// 不返回null
--->postProcessBeforeInstantiation ---在方法实例化之前执行  Bean对象还没有
执行了构造方法------User 被实例化
<<postProcessAfterInitialization --Bean的自定义初始化方法执行完成之后执行--对象已经存在
User [id=0, name=null, beanName=null]

源码解析

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation


/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation 
* 作用:在实例化之前解析是否有快捷创建的Bean,就是通过postProcessBeforeInstantiation返回的Bean
*/
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);
					//如果返回了快捷的Bean
					if (bean != null) {
					    //如果postProcessBeforeInstantiation方法返回了快捷的Bean,内部遍历调用postProcessBeforeInstantiation方法【在初始化之后调用】
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
	
	/**
	*   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation
	*   作用:调用postProcessBeforeInstantiation方法
    */
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
    			throws BeansException {
	        //遍历所有的后置处理器
    		for (BeanPostProcessor bp : getBeanPostProcessors()) {
    		    //判断是否是InstantiationAwareBeanPostProcessor类型的,如果是的,调用postProcessBeforeInstantiation方法获取快捷Bean
    			if (bp instanceof InstantiationAwareBeanPostProcessor) {
    				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    				if (result != null) {
    					return result;
    				}
    			}
    		}
    		return null;
    	}
	
	/**
	*   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization
	*   作用:遍历调用postProcessAfterInitialization
	*/
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    			throws BeansException {
    		Object result = existingBean;
    		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    			result = beanProcessor.postProcessAfterInitialization(result, beanName);
    			if (result == null) {
    				return result;
    			}
    		}
    		return result;
    	}

populateBean 执行的时刻是:实例化之后调用,在方法applyPropertyValues【属性填充】之前

/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean
* 填充指定Bean的属性
* 在该方法内部遍历所有的BeanPostPorcessor,调用postProcessAfterInstantiation方法
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        //获取属性
		PropertyValues pvs = mbd.getPropertyValues();
		if (bw == null) {
			if (!pvs.isEmpty()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}
		// 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.
        //判断ioc容器中是否存在InstantiationAwareBeanPostProcessors(
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		    //遍历所有的InstantiationAwareBeanPostProcessor
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
       PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
			PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					// 执行 postProcessPropertyValues 设置值
					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		//重要的一步,设置属性
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值