1. 程式人生 > 實用技巧 >Spring AOP實現原理

Spring AOP實現原理

AOP實現原理:

  編織:
  靜態編織 通過修改原始碼或位元組碼在編譯器、後編譯器或載入器嵌入程式碼
  動態編織 通過代理等技術在執行期實現嵌入。【AspectJ,Spring】

  AOP是什麼?
  AOP(Aspect Orient Programming),我們一般稱為面向方面(切面)程式設計,作為面向物件的一種補充,用於處理系統中分佈於各個模組的橫切關注點,比如事務管理、日誌、快取等等。AOP實現的關鍵在於AOP框架自動建立的AOP代理,AOP代理主要分為靜態代理和動態代理,靜態代理的代表為AspectJ;而動態代理則以Spring AOP為代表。本文會分別對AspectJ和Spring AOP的實現進行分析和介紹。

  Spring AOP如何實現的?
  Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理。JDK動態代理通過反射來接收被代理的類,並且要求被代理的類必須實現一個介面。JDK動態代理的核心是InvocationHandler介面和Proxy類。
  如果目標類沒有實現介面,那麼Spring AOP會選擇使用CGLIB來動態代理目標類。CGLIB(Code Generation Library),是一個程式碼生成的類庫,可以在執行時動態的生成某個類的子類,注意,CGLIB是通過繼承的方式做的動態代理,因此如果某個類被標記為final,那麼它是無法使用CGLIB做動態代理的。

  JDK動態代理
  package com.zb.zbook.z_springaop;
  public interface Service {
    /**add方法*/
    void add();
    /**update方法*/
    void update();
  }

  package com.zb.zbook.z_springaop;
  public class ServiceImpl implements Service{
    @Override
    public void add() {
        System.out.println("AService add >>>>>>>>>");
    }

    @Override
    public void update() {
        System.out.println("AService update >>>>>>>>>");
    }
  }

  實現動態代理類MyInvocationHandler,實現InvocationHandler介面,並且實現介面中的invoke方法。仔細看invoke方法,就是在該方法中加入切面邏輯的。目標類方法的執行是由mehod.invoke(target,args)這條語句完成。
  package com.zb.zbook.z_springaop;
  import org.springframework.cglib.proxy.InvocationHandler;
  import java.lang.reflect.Method;
  public class MyInvocationHandler implements InvocationHandler {
    private Object target;
    public MyInvocationHandler(Object object){
      super();
      this.target = object;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("=========before=========");
        //程式執行
        Object result = method.invoke(target, args);
        //程式執行後加入邏輯,MethodAfterAdviceInterceptor
        System.out.println("=========after==========");
        return result;
    }
  }

  測試類,其中增強的目標物件是由Proxy.newProxyInstance(aService.getClass().getClassLoader(),aService.getClass().getInterfaces(), handler);來生成的。
  package com.zb.zbook.z_springaop;
  import org.springframework.cglib.proxy.InvocationHandler;
  import java.lang.reflect.Method;

  public class MyInvocationHandler implements InvocationHandler {

  private Object target;

  public MyInvocationHandler(Object object){
        super();
        this.target = object;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("=========before=========");
    //程式執行
    Object result = method.invoke(target, args);
    //程式執行後加入邏輯,MethodAfterAdviceInterceptor
    System.out.println("=========after==========");
    return result;
  }
  }