当前位置: 首页 > 编程笔记 >

spring aop之链式调用的实现

宣望
2023-03-14
本文向大家介绍spring aop之链式调用的实现,包括了spring aop之链式调用的实现的使用技巧和注意事项,需要的朋友参考一下

概述

AOP(Aspect 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

实现MethodInvocation,proceed()方法递归实现链式调用。

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Javasript设计模式之链式调用详解,包括了Javasript设计模式之链式调用详解的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js设计模式之链式调用的具体代码,供大家参考,具体内容如下 写过jquery的可能都知道,jquery里面可以很方便的使用以下代码: 而jquery这种调用方式就是链式调用。我们可以从上述代码看出来,如果不使用链式调用的话,那么我们

  • 问题 你想调用一个对象上的多个方法,但不想每次都引用该对象。 解决方案 在每次链式调用后返回 this(即@)对象 class CoffeeCup constructor: -> @properties= strength: 'medium' cream: false sugar: false

  • 这样的函数怎么实现。 这样操作需要 new Sint(1,2) ,有什么办法可以实现直接 Sint(1,2).j(10) 输出结果吗?

  • 本文向大家介绍jQuery是如何链式调用的?相关面试题,主要包含被问及jQuery是如何链式调用的?时的应答技巧和注意事项,需要的朋友参考一下 返回对象本身即可,类似 , 那么 obj.func().func() 可以无限而链式的调用下去。 而函数内的 obj 往往也可以用 this 来轻松方便地取代。

  • 我正在尝试学习一些RxJava和RxAndroid,我认为我遇到的问题可以很容易地使用这样的工具来解决。问题是:我们可以在一个活动中有“N”个视图,并且每个视图都用于满足某些条件。当用户按“保存”时,我们想检查所有视图中是否满足所有条件,如果不满足,请用户分别确认每个视图。所以这是我在没有RxJava的情况下如何处理这个问题的示例: 显然,我需要某种类型的监听器来确认结果,并且在条件被确认后(使用

  • 我有一个问题,我没有得到我的交易被提交 我的服务类是@Transactional注释的 我的类有3个api,它们在内部调用各自的Dao,而Dao没有被注释为事务性的。 现在如果我调用取消,我会先调用查找,然后调用返回()。但是返回()需要查找()需要将数据库更新为FIND状态。 但是,由于所有操作都发生在同一事务上,直到返回取消,所以不会提交事务。有人能帮我理解这种情况并解决它吗。 我不知道在这种