首页 > 编程 > Java > 正文

spring aop之链式调用的实现

2019-11-26 09:16:01
字体:
来源:转载
供稿:网友

概述

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<MethodInterceptor> interceptorList;  private int currentInterceptorIndex = -1;  public ReflectiveMethodInvocation(Object targetObject, Method targetMethod, List<MethodInterceptor> 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<MethodInterceptor> 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 tx
http://niocoder.com/
commit tx

时序图 beforeAdvice->afterReturningAdvice

afterReturningAdvice->beforeAdvice

修改interceptorList的顺序

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

输出:

start tx
http://niocoder.com/
commit tx

时序图 afterReturningAdvice->beforeAdvice

代码下载

github:https://github.com/longfeizheng/data-structure-java/blob/master/src/main/java/cn/merryyou/aop

代码下载

github:https://github.com/longfeizheng/data-structure-java

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表