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

本文共 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://lbbua.baihongyu.com/

你可能感兴趣的文章
从0开始学Flutter
查看>>
mysql操作入门基础之对数据库和表的增删改查
查看>>
IIS负载均衡
查看>>
分布式事务,EventBus 解决方案:CAP【中文文档】
查看>>
Linux下的CPU性能瓶颈分析案例
查看>>
spring mvc入门
查看>>
2012在数据库技术会议上的讲话PPT打包
查看>>
【Android】 TextView设置个别字体样式
查看>>
python svn
查看>>
raise语句
查看>>
sequence2(高精度dp)
查看>>
ABP实战--集成Ladp/AD认证
查看>>
存储过程
查看>>
phpcms v9栏目列表调用每一篇文章内容方法
查看>>
python 自定义信号处理器
查看>>
luov之SMTP报错详解
查看>>
软件概要设计做什么,怎么做
查看>>
dwr
查看>>
java的特殊符号
查看>>
word2010中去掉红色波浪线的方法
查看>>