在写这篇文章前,在网上看了一下大多数的文章,在说这一块时,都是用语言来表达的。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. 简单事件机制Java实现

    一个很简单方便的事件处理方法. 使用效果 事件发布者: //定义事件 public static EventTrans<String> AuthFailed = new EventTran ...

  2. Entity Framework 6 Recipes 2nd Edition(9-2)译->用WCF更新单独分离的实体

    9-2. 用WCF更新单独分离的实体 问题 你想通过WCF为一个数据存储发布查询,插入,删除和修改,并且使这些操作尽可能地简单 此外,你想通过Code First方式实现EF6的数据访问管理 解决方案 ...

  3. dom 操作

    1.dom 的查找 (1)根据id 查找 var object = document.getElementById("id 值"): (2)根据 name 查找:返回 dom 对象 ...

  4. 【Win 10 应用开发】UDP广播

    我们知道,对于UDP协议的通信,除了可以用来聊天外,可以发送广播数据.只要向广播地址的某个端口发送数据就可以进行广播,子网中只要监听该端口的socket就能收到广播消息. 最简单的方法就是向255.2 ...

  5. 为WLW开发Latex公式插件

    WLW是写博客的利器,支持离线.格式排版等,而且拥有众多的插件.博客园推荐了代码插入插件,但是没有提供WLW的公式编译插件.目前我的一般做法是:先在Word下使用MathType编辑好公式,然后将公式 ...

  6. 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)

    今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...

  7. ASP.NET MVC 5调用其他Action

    引用代码: @Html.Action("Index", "BaseData", new { d = "variety" }) 后台获取参数: ...

  8. ios 开发需要看的书籍

    1.吴航写的<iOS应用逆向工程 第2版> 2.<iOS 应用安全攻防实战> 3.

  9. vim 编辑器简单使用总结

    http://blog.csdn.net/sharp_allen/article/details/27075133转载 说了这么多,其实还少一个和word,记事本一样的编辑器,在各个操作系统都有编辑器 ...

  10. HTML5 网络拓扑图整合 OpenLayers 实现 GIS 地图应用

    在前面<百度地图.ECharts整合HT for Web网络拓扑图应用>我们有介绍百度地图和 HT for Web 的整合,我们今天来谈谈 OpenLayers 和 HT for Web  ...