在上篇博客中写道了 bean 后置处理器 InstantiationAwareBeanPostProcessor, 只介绍了其中一个方法的作用及用法, 现在来看 postProcessBeforeInstantiation 方法.
一, 概述
postProcessBeforeInstantiation 方法定义在 InstantiationAwareBeanPostProcessor 接口中, 方法的定义如下,
- @Nullable
- default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
- return null;
- }
从上面的代码中可以看到该方法默认返回 null.
二, 详述
postProcessBeforeInstantiation 方法是用来做什么的, 在看源码的过程中, 在 createBean 方法中找到了该方法的调用, 下面只贴出相关代码,
- try {
- // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
- //1, 调用 beanPostProcessor 即 bean 的后置处理器, 这里会调用 2 次后置处理器
- Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
- if (bean != null) {
- return bean;
- }
- }
- catch (Throwable ex) {
- throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
- "BeanPostProcessor before instantiation of bean failed", ex);
- }
在 resolveBeforeInstantiation 方法中进行了调用, resolveBeforeInstantiation 方法返回值如果不为 null, 则该方法直接返回 bean, 也就是说 resolveBeforeInstantiation 方法至关重要, 下面是 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.
- if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
- Class<?> targetType = determineTargetType(beanName, mbd);
- if (targetType != null) {
- // 如果是 InstantiationAwareBeanPostProcessor 的实例, 则执行其 postProcessBeforeInstantiation 方法
- bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
- // 如果上面的 postProcessBeforeInstantiation 方法返回值不为 null, 则执行所有 beanPostProcessor 的 postProcessAfterInitialization 方法
- //bean 不为 null, 则说明 postProcesBeforeInstantiation 方法中的返回值是一个不为 null 的对象
- if (bean != null) {
- bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
- }
- }
- }
- mbd.beforeInstantiationResolved = (bean != null);
- }
- return bean;
- }
在 resolveBeforeInstantiation 方法中首先调用了 applyBeanPostProcessorsBeforeInstantiation 方法, 该方法中便会调用 InstantiationAwareBeanPostProcessor 接口中的 postProcessBeforeInstantiation 方法, 且如果 applyBeanPostPorcessorsBeforeInstantiation 方法返回值不为 null, 才会调用 applyBeanPostProcessAfterIntialization 方法, 下面先看 applyBeanPostProcessorsBeforeInstantiation 方法
- @Nullable
- protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- if (bp instanceof InstantiationAwareBeanPostProcessor) {
- InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
- Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
- if (result != null) {
- return result;
- }
- }
- }
- return null;
- }
从上面方法的定义看到, 该方法会遍历 benaFactory 中的 beanPostProcessor, 并且判断是否为 InstantiationAwareBeanPostPrecessor 的类型, 如果是执行其 postProcessBeforeInstantiation 方法, 这里默认注册的 beanPostProcessor 该方法的返回值均为 null. 稍后自定义一个 BeanPostProcessor 实现 InstantiationAwareBeanPostProcessor 接口.
下面看 applyBeanPostProcessAfterIntializtion 方法,
- @Override
- public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
- throws BeansException {
- Object result = existingBean;
- for (BeanPostProcessor processor : getBeanPostProcessors()) {
- Object current = processor.postProcessAfterInitialization(result, beanName);
- if (current == null) {
- return result;
- }
- result = current;
- }
- return result;
- }
改方法的逻辑是遍历 beanFactory 中的所有的 beanPostProcessor, 执行其 postProcessAfterInitialization 方法, 该方法定义在 BeanPostProcessor 接口中, 默认返回 bean, 如下,
- @Nullable
- default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
从上面可以看出默认返回的是 bean 参数的值, 也就是如果该方法未实现则默认返回参数中的 bean.
再次回到 resolveBeforeInstantiation 方法, 再看其逻辑有以下几种方法返回值的组合,
1,applyBeanPostProcessBeforeInstantiation 返回值为 null, 则 resolveBeforeInstantiation 方法返回 null;
2,applyBeanPostProcessBeforeInstantiation 返回值 bean 不为 null,applyBeanPostProcessAfterInitialization 方法返回值为 null, 则 resolveBeforeInstantiationf 方法返回值为 bean;
3,applyBeanPostProcessBeforeInstantiation 返回值 bean 不为 null,applyBeanPostProcessAfterInitialization 方法返回值 bean1 不为为 null, 则 resolveBeforeInstantiationf 方法返回值为 bean1;
从 resolveBeforeInstantiation 方法分析, 该方法的返回值, 直接决定了 createBean 方法的返回值, 也就是说 applyBeanPostProcessBeforeInstantiation 方法返回的 bean 不为 null, 下面的方法不会执行.
再来看调用 resolveBeforeInstantiation 方法时的注释
- // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
- Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
大体意思时给 BeanPostProcessor 一个机会返回代理对象而不是目标对象的实例, 所以这里 resolveBeforeInstantiation 方法返回的必然时一个代理对象 (JDK 和 CGLib). 看下面的例子
自定义的 BeanPostProcessor 实现了 InstantiationAwareBeanPostProcessor
- package cn.com.my.test;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
- import org.springframework.stereotype.Component;
- import.NET.sf.cglib.proxy.Enhancer;
- @Component
- public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- // TODO Auto-generated method stub
- if("userService".equals(beanName)) {
- UserService us=(UserService)bean;
- Enhancer enhancer = new Enhancer();
- // 设置目标类的字节码文件
- enhancer.setSuperclass(UserService.class);
- // 设置回调函数
- enhancer.setCallback(new MyMethodInterceptor());
- // 这里的 creat 方法就是正式创建代理类
- UserService proxyUs = (UserService)enhancer.create();
- return proxyUs;
- }
- return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
- }
- }
当 beanName 等于 userUservice 时返回的是经过 cglib 代理后的对象. 在 MyInstantiationAwareBeanPostProcessor 类中仅实现了 postProcessBeforeInitialization 方法, 未实现 postProcessAfterInitialization 方法, 所以 resolveBeforeInstantiation 方法的返回值即未 postProcessBeforeInitialization 方法的返回值, 在上面的类中就是使用 cglib 代理后的 UserService 实例.
代理类 MyMethodInterceptor, 实现 cglib 的 MethodInterceptor 接口
- package cn.com.my.test;
- import java.lang.reflect.Method;
- import org.springframework.cglib.proxy.MethodProxy;
- import.NET.sf.cglib.proxy.MethodInterceptor;
- public class MyMethodInterceptor implements MethodInterceptor{
- @Override
- public Object intercept(Object arg0, Method arg1, Object[] arg2, net.sf.cglib.proxy.MethodProxy arg3)
- throws Throwable {
- // TODO Auto-generated method stub
- Object object = arg3.invokeSuper(arg0, arg2);
- return object;
- }
- }
下面是测试类
- package cn.com.my.test;
- import org.springframework.context.annotation.AnnotationConfigApplicationContext;
- public class Test {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(Config.class);
- UserService us=ac.getBean(UserService.class);
- System.out.println("us:"+us);
- }
- }
看下面的结果,
us:cn.com.my.test.UserService$$EnhancerByCGLIB$$ffa582b4@5fe94a96
返回的是 UserService 的一个经过 cglib 代理后的对象. 到这里发现真好强大, 返回的一个代理对象.
三, 适用场合
实现 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInitialization 方法, 通过返回一个代理对象的方式, 达到改变目标类类型的目的. 在不想改变现有类的逻辑而又想借助现有类实现其他功能, 就可以使用这种方式. 像 AOP 就是这种实现, AnnotationAwareAspectJAutoProxyCreator 类便是 InstantiationAwareBeanPostProcessor 的一个实现.
原创不易, 有不当之处, 欢迎指正, 谢谢!
来源: https://www.cnblogs.com/teach/p/12642349.html