在写这篇文章前,在网上看了一下大多数的文章,在说这一块时,都是用语言来表达的。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 的原理的更多相关文章

  1. 基于注解的Spring AOP的配置和使用

    摘要: 基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不 ...

  2. 基于注解的Spring AOP的配置和使用--转载

    AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  3. Spring AOP 注解和xml实现 --转载

    AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  4. Spring AOP 五大通知类型

    1.前置通知 在目标方法执行之前执行执行的通知. 前置通知方法,可以没有参数,也可以额外接收一个JoinPoint,Spring会自动将该对象传入,代表当前的连接点,通过该对象可以获取目标对象 和 目 ...

  5. Spring AOP详细介绍

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Asp ...

  6. spring AOP自定义注解方式实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  7. 关于 Spring AOP (AspectJ) 该知晓的一切

    关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上 ...

  8. Spring AOP 切面编程记录日志和接口执行时间

    最近客户现在提出系统访问非常慢,需要优化提升访问速度,在排查了nginx.tomcat内存和服务器负载之后,判断是数据库查询速度慢,进一步排查发现是因为部分视图和表查询特别慢导致了整个系统的响应时间特 ...

  9. spring AOP自定义注解 实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

随机推荐

  1. ABP源码分析二十三:Authorization

    Permission:用于定义一个Permission,一个permission可以包含多个子Permission. PermissionDictionary:继承自Dictionary<str ...

  2. Oracle---------sql 中取值两列中值最大的一列

    1.表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列. select (case when a>b then a else b ...

  3. React Native 环境搭建

    1,安装 HomeBrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install ...

  4. ASP.net 使用ConfigurationManager获取连接字符串

    在解决方案资源管理器里右键单击解决方案选择“添加引用”,并且从 .net 中找到 System.Configuration 引用它 在项目的web.config文件中添加 <connection ...

  5. 【.net 深呼吸】连接Access数据库应注意的几点

    本地数据库可以有Y种选择,比如Sqlite.SQL Server Express.SQL Local DB.SQL Server CE.Access等,本文老周选用比较著名的Access本地数据库,在 ...

  6. 从零开始编写自己的C#框架(20)——框架异常处理及日志记录

    最近很忙,杂事也多,所以开发本框架也是断断续续的,终于在前两天将前面设定的功能都基本完成了,剩下一些小功能遗漏的以后发现再补上.接下来的章节主要都是讲解在本框架的基础上进行开发的小巧. 本框架主要有四 ...

  7. [.NET] WebApi 生成帮助文档及顺便自动创建简单的测试工具

    ==========最终的效果图========== ==========下面开始干活:生成帮助文档========== 一.创建 WebApi 项目 二.找到 HelpPageConfig.cs 并 ...

  8. Git 常用命令

    一.初始環境配置 git config --global user.name "John Doe"git config --global user.email johndoe@ex ...

  9. 欢迎阅读daxnet的新博客:一个基于Microsoft Azure、ASP.NET Core和Docker的博客系统

    2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客.当然,我写博客也不是从2008年才开始的,在更早时候,也在CSDN和系统分析员协会(之后名为"希赛网" ...

  10. Javascript本地存储小结

    前言 总括:详细讲述Cookie,LocalStorge,SesstionStorge的区别和用法. 人生如画,岁月如歌. 原文博客地址:Javascript本地存储小结 知乎专栏&& ...