Spring的bean创建过程分析之resolveBeforeInstantiation的调用执行
我们接着上面的
Bean
的创建流程,今天来谈谈resolveBeforeInstantiation
的调用执行。
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
方法区调用执行的,并生成代理对象的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。