Spring:Aop before after afterReturn afterThrowing around 的原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
    }
}

 

以上是关于Spring:Aop before after afterReturn afterThrowing around 的原理的主要内容,如果未能解决你的问题,请参考以下文章

Spring AOP @Around @Before @After 区别

Spring AOP @Before @Around @After 等 advice 的执行顺序

Spring入门之AOP实践:@Aspect + @Pointcut + @Before / @Around / @After

Spring AOP @before@after@around@afterreturning@afterthrowing执行顺序

[技术分享]20171214_spring_@Before @After @AfterReturning @Around @AfterThrowing spring aop 的advise(通知)(

Spring AOP 中 advice 的四种类型 before after throwing advice around