spring aop之鏈式調用的實現

這篇文章主要介紹了spring aop之鏈式調用的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

概述

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持神馬文庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章