Spring的bean创建过程分析之resolveBeforeInstantiation的调用执行
作者:互联网
Spring的bean创建过程分析之resolveBeforeInstantiation的调用执行
我们接着上面的
Bean
的创建流程,今天来谈谈resolveBeforeInstantiation
的调用执行。此方法存在的意义在于给BeanPostProcessor的实现子类一个机会去生成代理对象来替代对象。
顾名思义, 我们需要生成的对象是一个代理对象。 这样也可以创建bean。
1、案例实现
- BeforeInstantiation.java
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 ...");
}
}
- QzkMethodInterceptor.java
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配置文件
<?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
接口的,针对这个接口,我们可以先看一下他的一个类图的继承关系。
根据上图所示, 因此, QzkInstantiationAwareBeanPostProcessor
在实现 InstantiationAwareBeanPostProcessor
接口之后,是属于 BeanPostProcessor的,因此在refresh()
的流程中, 是通过registerBeanPostProcessors(beanFactory)
方式, 实现的一个BPP
的创建的。
当我们执行 finishBeanFactoryInitialization(beanFactory)
的时候, 里面继续执行到 preInstantiateSingletons
紧接着就是执行我们的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
的。
上图就是通过拦截器来进行执行的操作结果。
总结:
- Spring 中bean的创建, 还可以通过 实现了
InstantiationAwarePostProcessor
接口的类 , 并结合动态代理去实现创建我们所需要的动态代理对象。 - 这个过程是通过
resolveBeforeInstantiation
方法区调用执行的,并生成代理对象的。
标签:Object,return,resolveBeforeInstantiation,Spring,beanName,bean,qzk,public 来源: https://www.cnblogs.com/qianzhengkai/p/16257639.html