博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring aop 之链式调用
阅读量:7065 次
发布时间:2019-06-28

本文共 5333 字,大约阅读时间需要 17 分钟。

关关雎鸠,在河之洲。窈窕淑女,君子好逑。

概述

AOPAspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。 Spring AOP采用的是动态代理,在运行期间对业务方法进行增强,所以不会生成新类,Spring AOP提供了对JDK动态代理的支持以及CGLib的支持。本章我们不关注aop代理类的实现,我简单实现一个指定次序的链式调用。

实现链式调用的

MethodInterceptor定义拦截器链,MethodInvocation 递归进入下一个拦截器链中。类图如下:

MethodInterceptor

public interface MethodInterceptor {    Object invoke(MethodInvocation invocation) throws Throwable;}

MethodInvocation

public interface MethodInvocation {    Object proceed() throws Throwable;}

AbstractAspectJAdvice

抽象类,实现MethodInterceptor

public abstract class AbstractAspectJAdvice implements MethodInterceptor{    private Method adviceMethod;    private Object adviceObject;    public AbstractAspectJAdvice(Method adviceMethod, Object adviceObject) {        this.adviceMethod = adviceMethod;        this.adviceObject = adviceObject;    }    public Method getAdviceMethod() {        return this.adviceMethod;    }    public void invokeAdviceMethod() throws Throwable {        adviceMethod.invoke(adviceObject);    }}

AspectJBeforeAdvice

前置通知

public class AspectJBeforeAdvice extends AbstractAspectJAdvice {    public AspectJBeforeAdvice(Method method, Object adviceObject) {        super(method, adviceObject);    }    @Override    public Object invoke(MethodInvocation invocation) throws Throwable{        this.invokeAdviceMethod();        Object o = invocation.proceed();        return o;    }}

AspectJAfterReturningAdvice

后置通知

public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice {    public AspectJAfterReturningAdvice(Method method, Object adviceObject) {        super(method, adviceObject);    }    @Override    public Object invoke(MethodInvocation invocation) throws Throwable{        Object o = invocation.proceed();        this.invokeAdviceMethod();        return o;    }}

ReflectiveMethodInvocation

实现MethodInvocationproceed()方法递归实现链式调用。

public class ReflectiveMethodInvocation implements MethodInvocation {    private final Object targetObject;    private final Method targetMethod;    private final List
interceptorList; private int currentInterceptorIndex = -1; public ReflectiveMethodInvocation(Object targetObject, Method targetMethod, List
interceptorList) { this.targetObject = targetObject; this.targetMethod = targetMethod; this.interceptorList = interceptorList; } @Override public Object proceed() throws Throwable { if (this.currentInterceptorIndex == this.interceptorList.size() - 1) { return invokeJoinPoint(); } this.currentInterceptorIndex++; MethodInterceptor interceptor = this.interceptorList.get(this.currentInterceptorIndex); return interceptor.invoke(this); } private Object invokeJoinPoint() throws Throwable { return this.targetMethod.invoke(this.targetObject); }}

NioCoderService

模拟service

public class NioCoderService {    public void testAop() {        System.out.println("http://niocoder.com/");    }}

TransactionManager

模拟通知类

public class TransactionManager {    public void start() {        System.out.println("start tx");    }    public void commit() {        System.out.println("commit tx");    }    public void rollback() {        System.out.println("rollback tx");    }}

ReflectiveMethodInvocationTest

beforeAdvice->afterReturningAdvice

测试类,测试通知

public class ReflectiveMethodInvocationTest {    private AspectJBeforeAdvice beforeAdvice = null;    private AspectJAfterReturningAdvice afterReturningAdvice = null;    private NioCoderService nioCoderService;    private TransactionManager tx;    public void setUp() throws Exception {        nioCoderService = new NioCoderService();        tx = new TransactionManager();        beforeAdvice = new AspectJBeforeAdvice(TransactionManager.class.getMethod("start"), tx);        afterReturningAdvice = new AspectJAfterReturningAdvice(TransactionManager.class.getMethod("commit"), tx);    }    public void testMethodInvocation() throws Throwable {        Method method = NioCoderService.class.getMethod("testAop");        List
interceptorList = new ArrayList<>(); interceptorList.add(beforeAdvice); interceptorList.add(afterReturningAdvice); ReflectiveMethodInvocation mi = new ReflectiveMethodInvocation(nioCoderService, method, interceptorList); mi.proceed(); } public static void main(String[] args) throws Throwable { ReflectiveMethodInvocationTest reflectiveMethodInvocationTest = new ReflectiveMethodInvocationTest(); reflectiveMethodInvocationTest.setUp(); reflectiveMethodInvocationTest.testMethodInvocation(); }}

输出:

start txhttp://niocoder.com/commit tx
时序图 beforeAdvice->afterReturningAdvice

afterReturningAdvice->beforeAdvice

修改interceptorList的顺序

public void testMethodInvocation() throws Throwable {        Method method = NioCoderService.class.getMethod("testAop");        List
interceptorList = new ArrayList<>(); interceptorList.add(afterReturningAdvice); interceptorList.add(beforeAdvice); ReflectiveMethodInvocation mi = new ReflectiveMethodInvocation(nioCoderService, method, interceptorList); mi.proceed(); }

输出:

start txhttp://niocoder.com/commit tx
时序图 afterReturningAdvice->beforeAdvice

代码下载

  • github:

代码下载

  • github:

转载地址:http://ufill.baihongyu.com/

你可能感兴趣的文章
java性能优化读书笔记(1)
查看>>
【转】nGrinder 简易使用教程
查看>>
Java中char转为16进制
查看>>
Linux下逻辑地址、线性地址、物理地址详细总结
查看>>
go 类型转换
查看>>
Linux常用基本命令:三剑客命令之-awk数组用法
查看>>
Ubuntu x86-64汇编(5) 控制指令
查看>>
curl如何发送json数据?如何发送form数据?python的restfull又该如何获取这些数据?...
查看>>
如何生成16位流水号
查看>>
Linux下 jenkins 的 使用
查看>>
nmap基本使用方法
查看>>
2018年高教社杯全国大学生数学建模竞赛B题解题思路
查看>>
解决Eclipse报errors running builder ‘javascript validator’ on project
查看>>
[Nuget]使用Nuget管理工具包
查看>>
【转】Spring Framework灰度发布
查看>>
Android自定义view双缓存技术
查看>>
支持 Windows 10 最新 PerMonitorV2 特性的 WPF 多屏高 DPI 应用开发
查看>>
linux查看硬件信息及驱动设备相关整理
查看>>
REST与SOA两种架构下WCF的异同比较(含源码)
查看>>
遇事处理方式
查看>>