Spring:Aop before after afterReturn afterThrowing around 的原理

时间:2023-03-09 16:46:08
Spring:Aop before after afterReturn afterThrowing around 的原理

在写这篇文章前,在网上看了一下大多数的文章,在说这一块时,都是用语言来表达的。before、after、afterReturn、afterThrowing 这四个用语言是可以说清楚的,但 around用语言来讲可就晦涩难懂了。

这里,我用代码来展示before、after、afterReturn、afterThrowing 、around是如何执行的。

不使用Around时,实现可以理解成这样的:

public class XxxProxy implement InvocationHandler {
    private Target target;
    private Interceptor interceptor;

    public Object invoke(Object proxy, Method method, Object[] args) throws Exception{
        interceptor.before();
        boolean hasReturnValue = method.getReturnType!=void.class;
        try{
            Object result = null;
            if(hasReturnValue){
                result = method.invoke(target, args);
            }else{
                method.invoke(target, args);
            }
            interceptor.afterReturn();
            return result;
        }catch(Exception ex){
            interceptor.afterThrowing();
            throw ex;
        }finally{
            interceptor.after();
        }
    }
}

使用Around时,实现可以理解成这样的

public class XxxProxy implement InvocationHandler {
    private Target target;
    private Interceptor interceptor;

    public Object invoke(Object proxy, Method method, Object[] args) throws Exception{
        interceptor.before();
        boolean hasReturnValue = method.getReturnType!=void.class;
        try{
            ProxyMethodInvocation methodInvocation = new ReflectiveMethodInvocation(proxy, method, target, args);
            ProceedingJoinPoint proceed = new MethodInvocationProceedingJoinPoint(target, parameters);
            Object result = null;
            // 通过Around 来执行 真实的方法调用
            if(hasReturnValue){
                result = interceptor.around(proceed); // 在编写around方法中必须得调用 proceed.procced();
            }else{
                interceptor.around(proceed);
            }
            interceptor.afterReturn();
            return result;
        }catch(Exception ex){
            interceptor.afterThrowing();
            throw ex;
        }finally{
            interceptor.after();
        }
    }
}

public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
    private Object proxy;
    private Object target;
    private Method method;
    private Object[] args;

    public ReflectiveMethodInvocation(Object proxy, Method method, Object target, Object[] args){
        this.proxy = proxy;
        this.method = method;
        this.target = target;
        this.args = args;
    }

    public Method getMethod(){
        return this.method;
    }
    public Object[] getArgs(){
        return args;
    }
    public Object[] getTarget(){
        return target;
    }

}

public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint{
    private ProxyMethodInvocation methodInvocation;
    public MethodInvocationProceedingJoinPoint(ProxyMethodInvocation methodInvocation){
        this.methodInvocation = methodInvocation;
    }

    public Object procced(){
        Object target = methodInvocation.getTarget();
        Object[] args = methodInvocation.getArgs();
        Method method = methodInvocation.getMethod();
        return method.invoke(target, args);
    }
}