其他分享
首页 > 其他分享> > Spring的bean创建过程分析之resolveBeforeInstantiation的调用执行

Spring的bean创建过程分析之resolveBeforeInstantiation的调用执行

作者:互联网

Spring的bean创建过程分析之resolveBeforeInstantiation的调用执行

我们接着上面的Bean 的创建流程,今天来谈谈 resolveBeforeInstantiation 的调用执行。

此方法存在的意义在于给BeanPostProcessor的实现子类一个机会去生成代理对象来替代对象。

顾名思义, 我们需要生成的对象是一个代理对象。 这样也可以创建bean。

1、案例实现

package com.qzk.QzkResolveBeforeInstantiation;

/**
 * @ClassName BeforeInstantiation
 * @Description 创建一个 BeforeInstantiation 的一个类, 该类只有一个方法, do some things
 * @Author qzk
 * @Date 2022/4/26 11:43 下午
 * @Version 1.0
 **/
public class BeforeInstantiation {

    public void doSomething(){
        System.out.println(" 执行do some thing ...");
    }
}
package com.qzk.QzkResolveBeforeInstantiation;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 *
 * @ClassName QzkMethodInterceptor
 * @Description 拦截器
 * @Author qzk
 * @Date 2022/4/26 11:52 下午
 * @Version 1.0
 **/
public class QzkMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("目标方法执行之前: " + method);
        Object o1 = methodProxy.invokeSuper(o, objects);
        System.out.println("目标方法执行之后: " + method);
        return o1;
    }
}

package com.qzk.QzkResolveBeforeInstantiation;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;

/**
 * @ClassName QzkInstantiationAwareBeanPostProcessor
 * @Description
 * @Author qzk
 * @Date 2022/4/26 11:45 下午
 * @Version 1.0
 **/
public class QzkInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {


    /**
     * 实例化之前的操作
     *
     * @param beanClass the class of the bean to be instantiated
     * @param beanName  the name of the bean
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

//        if (beanClass.equals(BeforeInstantiation.class)) {
            System.out.println("当前beanName:" + beanName + "--> 执行:postProcessBeforeInstantiation 实例化之前");
            if (beanClass == BeforeInstantiation.class) {
                // 创建动态代理类的增强类
                Enhancer enhancer = new Enhancer();
                //  设置类加载器
                enhancer.setClassLoader(beanClass.getClassLoader());
                //  设置被动态代理类所代理的 被代理类
                enhancer.setSuperclass(beanClass);
                // 设置方法拦截器
                enhancer.setCallback(new QzkMethodInterceptor());
                //  创建代理类
                BeforeInstantiation beforeInstantiation = (BeforeInstantiation) enhancer.create();
                System.out.println("创建代理对象:" + beforeInstantiation);
                return beforeInstantiation;
            }
            return nulll;
    }

    /**
     * 实例化之后的操作
     *
     * @param bean     the bean instance created, with properties not having been set yet
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("当前beanName:" + beanName + "--> 执行:postProcessAfterInstantiation 实例化之后");
        return false;
    }

    /**
     * 对当前属性值的一个相关处理工作
     *
     * @param pvs      the property values that the factory is about to apply (never {@code null})
     * @param bean     the bean instance created, but whose properties have not yet been set
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("当前beanName:" + beanName + "--> 执行:postProcessProperties 属性值的处理");
        return pvs;
    }

    /**
     * 初始化之前的做哪些操作
     *
     * @param bean     the new bean instance
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("当前beanName:" + beanName + "--> 执行:postProcessBeforeInitialization 初始化之前");

        return bean;
    }

    /**
     * 初始化之后做哪些操作
     *
     * @param bean     the new bean instance
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("当前beanName:" + beanName + "--> 执行:postProcessAfterInitialization 初始化之后");
        return bean;
    }
}

package com.qzk.QzkResolveBeforeInstantiation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ClassName QzkTest
 * @Description TODO
 * @Author qzk
 * @Date 2022/4/27 12:01 上午
 * @Version 1.0
 **/
public class QzkTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("QzkResolveBeforeInstantiation.xml");
        BeforeInstantiation bean = context.getBean(BeforeInstantiation.class);
        bean.doSomething();
    }
}

<?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 id="beforeInstantiation" class="com.qzk.QzkResolveBeforeInstantiation.BeforeInstantiation"></bean>
    <bean id="myInstantiationAwareBeanPostProcessor" class="com.qzk.QzkResolveBeforeInstantiation.QzkInstantiationAwareBeanPostProcessor"></bean>

</beans>

在上面的代码中,我们看到有一个类 是实现了InstantiationAwareBeanPostProcessor 接口的,针对这个接口,我们可以先看一下他的一个类图的继承关系。

image-20220511112055917

image-20220511112129120

image-20220511112232916

根据上图所示, 因此, QzkInstantiationAwareBeanPostProcessor在实现 InstantiationAwareBeanPostProcessor 接口之后,是属于 BeanPostProcessor的,因此在refresh() 的流程中, 是通过registerBeanPostProcessors(beanFactory) 方式, 实现的一个BPP的创建的。

image-20220511114439436

image-20220511114724401

当我们执行 finishBeanFactoryInitialization(beanFactory) 的时候, 里面继续执行到 preInstantiateSingletons

image-20220511115156851

紧接着就是执行我们的getBean --> doGetBean --> createBean ---> doCreateBean 的一个流程, 这里不做过多的赘述。

在具体的执行过程中, 我们自定义的 beforeInstatiation 此时会走下面的逻辑

![image-20220511132013946](/Users/qzk/Library/Application Support/typora-user-images/image-20220511132013946.png)

![image-20220511132209559](/Users/qzk/Library/Application Support/typora-user-images/image-20220511132209559.png)

![image-20220511132307893](/Users/qzk/Library/Application Support/typora-user-images/image-20220511132307893.png)

![image-20220511132451405](/Users/qzk/Library/Application Support/typora-user-images/image-20220511132451405.png)

当第二次for BeanName 循环的时候, 是获取 Qzk... ,此时执行到如下图的doGetBean 方法的时候,因为可以从缓存中获取到这个BPP,所以是通过 getObjetcForBeanInstance 方法来获取bean 的。

image-20220511133725933

image-20220511134454958

image-20220511134537873

上图就是通过拦截器来进行执行的操作结果。

总结:

标签:Object,return,resolveBeforeInstantiation,Spring,beanName,bean,qzk,public
来源: https://www.cnblogs.com/qianzhengkai/p/16257639.html