Bean后处理器的用处,由shiro配置想到的

一、BeanPostProcessor

BeanPostProcessor,实现这个接口之后允许对spring管理的bean进行增强处理。该接口主要有两个方法

Object postProcessBeforeInitialization(Object bean, String name) throws BeansException;

Object postProcessAfterInitialization(Object bean, String name) throws BeansException;

这两个方法的调用时机,

postProcessBeforeInitialization

                    |

bean的初始化过程

                    |

postProcessAfterInitialization

实际当中,spring提供了大量的bean后处理器,其中比较常用的两个bean后处理器就有

1、BeanNameAutoProxyCreator,这个是根据bean的名称,创建bean的实例代理

2、DefaultAdvisorAutoProxyCreator,这个是对容器中的所有实例创建代理,其中shiro根据注解对方法进行的权限管理就是基于这个处理器。

二、shiro怎么用的bean后处理器

1、DefaultAdvisorAutoProxyCreator的父类
AbstractAutoProxyCreator其中实现了postProcessAfterInitialization,在这个方法中,为spring中的bean创建代理类
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource)
2、创建aop代理可以看到,根据配置是创建jdk代理或者cglib代理,两者的区别一个基于接口,一个创建出子类
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
         throw new AopConfigException("TargetSource cannot determine target class: " +
               "Either an interface or a target is required for proxy creation.");
      }
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}
3、其实shiro是cglib形式代理的后面再专门讲下cglib代理,简单以JdkDynamicAopProxy为例,可以发现该类实现了InvocationHandler,这个类怎么用在《JAVA编程思想》有一块篇幅专门讲的。并且还有实例,具体就是根据接口创建的代理,需绑定具体实现类,以接口调用方法时,会执行实现了InvocationHandler里的invoke方法,这样就可以在调用方法前后执行aop操作。
JdkDynamicAopProxy的invoke方法里面
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
ReflectiveMethodInvocation对象中的proceed方法就是具体执行的方法了。实现了
MethodInterceptor就可以针对bean操作就行注入操作。

猜你喜欢

转载自my.oschina.net/u/1271447/blog/2967670