从零开始造Spring08---AOP(介绍以及实现ReflectiveMethodInvocation和AopProxyFactory)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014534808/article/details/81507273

前言

这是学习刘老师的《从零开始造Spring》的学习笔记,接上篇笔记从零开始造Spring07

如何实现指定次序的链式调用

SpringAOP定义的拦截器

Spring  AOP 定义的拦截器

从类图中我们可以看出Advice 接口继承了来自AOP Aliance 中的MethodInterceptor 类。该类中的invoke 方法通过传入Methodinvocation 对象,而Methodinvocation的proceed方法则是实现链式调用的关键。

ReflectiveMethodInvocation类实现了Methodinvocation 接口
ReflectiveMethodInvocation
如图我们可以看到ReflectiveMethodInvocation类的构造器中有3个参数,第一个参数是 待拦截的对象,第二个为 待拦截的方法,第三个为 拦截器列表。

关键代码实现

ReflectiveMethodInvocation 中的proceed方法

   @Override
    public Object proceed() throws Throwable {
        //所有拦截器调用完成
        if (this.currentInterceptorIndex == this.interceptors.size() - 1) {
            return invokeJoinpoint();
        }
        //currentInterceptorIndex初始值为-1
        this.currentInterceptorIndex++;
        MethodInterceptor interceptor = this.interceptors.get(this.currentInterceptorIndex);
        return interceptor.invoke(this);
    }

首先会检查传入的拦截器是否调用完成,如果调用完成则返回,否则,则先调用当前拦截器的invoke 方法。
AspectJBeforeAdvice 类的invoke方法

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
//        例如:调用TransactionManager的start方法
        this.invokeAdviceMethod();
        Object proceed = methodInvocation.proceed();
        return proceed;
    }

AspectJAfterReturningAdvice 类的invoke方法

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Object proceed = methodInvocation.proceed();
//        例如:调用TransactionManager的commit方法
        this.invokeAdviceMethod();
        return proceed;
    }

比较AspectJBeforeAdvice 类和AspectJAfterReturningAdvice类的invoke方法,我们发现一个明显的区别是invokeAdviceMethod 方法调用顺序,在AspectJBeforeAdvice中首先会调用自身的拦截方法之后才会调用其他的拦截器。在AspectJAfterReturningAdvice中必须等其他的拦截器调用完毕才会调用自身的拦截方法。这就实现了指定次序的链式调用。

相关测试代码

  @Test
    public void testMethodInvocation1() throws Throwable {
        Method targetMethod = PetStoreService.class.getMethod("placeOrder");

        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>();
        interceptors.add(afterAdvice);
        interceptors.add(beforeAdvice);

        ReflectiveMethodInvocation mi = new ReflectiveMethodInvocation(petStoreService, targetMethod, new Object[0], interceptors);
        mi.proceed();

        List<String> msgs = MessageTracker.getMsgs();
        Assert.assertEquals(3, msgs.size());
        Assert.assertEquals("start tx", msgs.get(0));
        Assert.assertEquals("place order", msgs.get(1));
        Assert.assertEquals("commit tx", msgs.get(2));
    }

通过Factory 获得代理实例

Cglib 动态代理

Cglib动态代理是通过扩展子类来实现对父类的增强。

 @Test
    public void testCallBack() {
        // Cglib的增强者
        Enhancer enhancer = new Enhancer();
//        设置父类
        enhancer.setSuperclass(PetStoreService.class);
        enhancer.setCallback(new TransactionInterceptor());
//        创建代理
        PetStoreService petStoreService = (PetStoreService) enhancer.create();
        petStoreService.placeOrder();

    }
    //Cglib定义的拦截器
    public static class TransactionInterceptor implements MethodInterceptor {
        TransactionManager txManager = new TransactionManager();
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            txManager.start();
            Object result = proxy.invokeSuper(obj, args);
            txManager.commit();
            return result;
        }
    }

通过Factory 获得代理实例

首先我们看一下类图
这里写图片描述
如类图所示
关键代码:

public class CglibProxyFactory implements AopProxyFactory {
   //在某种情况下选择对应的拦截器
    private static final int AOP_PROXY = 0;
    private static final int INVOKE_TARGET = 1;
    private static final int NO_OVERRIDE = 2;
    private static final int DISPATCH_TARGET = 3;
    private static final int DISPATCH_ADVISED = 4;
    private static final int INVOKE_EQUALS = 5;
    private static final int INVOKE_HASHCODE = 6;

    protected static final Log logger = LogFactory.getLog(CglibProxyFactory.class);

    protected final AopConfig config;

    private Object[] constructorArgs;

    private Class<?>[] constructorArgTypes;

    public CglibProxyFactory(AopConfig config) throws AopConfigException {
        Assert.notNull(config, "AdvisedSupport must not be null");
        if (config.getAdvices().size() == 0 /*&& config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE*/) {
            throw new AopConfigException("No advisors and no TargetSource specified");
        }
        this.config = config;

    }
  @Override
    public Object getProxy() {
         return getProxy(null);
    }
    //创建代理的方法
    @Override
    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.config.getTargetClass());
        }
        //拿到class对象
        Class<?> rootClass = this.config.getTargetClass();
        //实例化增强器
        Enhancer enhancer = new Enhancer();
        if (classLoader != null) {
            enhancer.setClassLoader(classLoader);
        }
        enhancer.setSuperclass(rootClass);
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);//"BySpringCGLIB"

        enhancer.setInterceptDuringConstruction(false);


        Callback[] callbacks = getCallbacks(rootClass);
        Class<?>[] types = new Class<?>[callbacks.length];
        for (int i = 0; i < types.length; i++) {
            types[i] = callbacks[i].getClass();
        }
        enhancer.setCallbackFilter(new ProxyCallbackFilter(this.config));
        enhancer.setCallbackTypes(types);
        enhancer.setCallbacks(callbacks);

        Object proxy = enhancer.create();
        return proxy;
    }

    private Callback[] getCallbacks(Class<?> rooClass) {
    //创建Callback
        Callback aopInterceptor = new DynamicAdvisedInterceptor(this.config);
        Callback[] callbacks = new Callback[] {
                aopInterceptor,  // AOP_PROXY for normal advice
                /*targetInterceptor,  // INVOKE_TARGET invoke target without considering advice, if optimized
                new SerializableNoOp(),  // NO_OVERRIDE  no override for methods mapped to this
                targetDispatcher,        //DISPATCH_TARGET
                this.advisedDispatcher,  //DISPATCH_ADVISED
                new EqualsInterceptor(this.advised),
                new HashCodeInterceptor(this.advised)*/
        };

        return callbacks;
    }

    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
        private final AopConfig config;

        public DynamicAdvisedInterceptor(AopConfig advised) {
            this.config = advised;
        }
        //
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            //获取targetObject
            Object target = this.config.getTargetObject();
            //获取advices列表
            List<Advice> chain = this.config.getAdvices(method);
            Object retVal;
            //列表为空,啥都不干
            if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                retVal = methodProxy.invoke(target, args);
            } else {
            //生成拦截器列表
                List<org.aopalliance.intercept.MethodInterceptor> interceptors =
                        new ArrayList<org.aopalliance.intercept.MethodInterceptor>();

                interceptors.addAll(chain);


                // We need to create a method invocation...
                retVal = new ReflectiveMethodInvocation(target, method, args, interceptors).proceed();

            }
            return retVal;
        }
    }
    /**
     * CallbackFilter to assign Callbacks to methods.
     */
    private static class ProxyCallbackFilter implements CallbackFilter {

        private final AopConfig config;
        public ProxyCallbackFilter(AopConfig advised) {
            this.config = advised;

        }


        public int accept(Method method) {
            // 注意,这里做了简化,永远返回第一个
            return AOP_PROXY;

        }

    }

代码地址

源码地址

猜你喜欢

转载自blog.csdn.net/u014534808/article/details/81507273