Spring AOP 雜談

其實AOP的思想如今講的已經不少了,自己沒有什麼難點,難的是AOP有本身的一套術語,而咱們常常被這套術語搞暈。術語沒招,只能理解背誦了,儘管背誦很討厭,可你們都這麼說,不知道,就會被說暈。html

AOP思想:以下圖,面向切面編程。就是「切「。執行本身的方法時,「在以前,以後,異常,返回,或者先後」都去順便執行一下其餘業務方法,切面就是其餘業務方法。java

AOP術語以下圖,簡單示例編程

通知:通知定義了切面是什麼以及什麼時候使用,首先該通知方法實現了「作什麼的代碼業務邏輯」,而後肯定了在何時執行。ide

前置通知:在目標方法調用以前調用通知。測試

後置通知:在目標方法完成以後調用通知。this

返回通知:在目標方法成功執行以後調用通知。spa

異常通知:在目標方法拋出異常後調用通知。代理

環繞通知:通知包裹了被通知的方法,在被通知的方法調用以前和以後執行的自定義行爲。htm

鏈接點:鏈接點 是在應用執行過程當中可以插入 切面 的一個點。這個點能夠是調用方法時、拋出異常時、甚至修改一個字段時。切面代碼能夠利用這些點插入到應用的正常流程之中,並添加新的行爲。對象

切點:切點就是在 「哪一個鏈接點或哪些鏈接點處」執行通知。定義了何處執行。

切面:通知+切點=切面 定義了 1.什麼時候2.何處3.幹什麼 這三要素。

 

如下的兩個概念定義瞭如何實現AOP

引入:引入容許咱們向現有的類添加新方法或屬性。而無需修改這些現有的類的狀況下,讓他們具備新的行爲和狀態。

織入:是切面應用到目標對象並建立新的代理對象的過程。

這兩個概念都是 「動做」

在目標對象的生命週期裏能夠有多個點進行織入(這裏要了解一下  java類的運行過程)

編譯期:切面在目標類編譯時被織入,這種方式須要特殊的編譯器。

類加載期:切面在目標類加載到JVM時被織入。這種方式須要特殊的類加載器(ClassLoader),它能夠在目標類被引入應用以前加強該目標類的字節碼。

運行期:切面在應用運行的某個時刻被織入。(通常狀況下,在織入切面時,AOP容器會爲目標對象動態的建立一個代理對象)

AOP實現

JAVA靜態代理 : 代理對象和被代理對象實現相同的接口。

//接口

public interface StaticProxy {
         void action();

}

//被代理類

public class BProxy implements StaticProxy {

  @Override
  public void action() {
    System.out.println(BProxy.class.getName()+":作一些事情");
  }

}

//代理類

public class DProxy implements StaticProxy{

  StaticProxy BProxy;

  public DProxy() {
    BProxy = new BProxy();
  }

  @Override
  public void action() {
    System.out.println(DProxy.class.getName()+":先作一些事情");
    BProxy.action();
    System.out.println(DProxy.class.getName()+":再作一些事情");
  }

}

 

JDK動態代理:動態代理類的字節碼在程序運行時由Java反射機制動態生成。java.lang.reflect 包中的Proxy類和InvocationHandler 接口提供了生成動態代理類的能力。一個類                               和一個接口實現。JDK動態代理的缺點:被代理類必須是實現接口的類。

//代理類 實現 InvocationHandler 

public class DynamicProxy implements InvocationHandler {

               private Object target;

               public DynamicProxy(Object target) {
                     this.target = target;
               }

               @Override
               public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                     //目標方法以前執行
                     System.out.println("do sth Before...");
                    //經過反射機制來調用目標類方法
                    Object result = method.invoke(target, args);
                    //目標方法以後執行
                    System.out.println("do sth After...\n");
                    return result;
               }

}

//供被代理類實現的接口

public interface userSrevices {

            public void addUser();

            public void deleteUser();

}

//實現接口的被代理類

public class userSrevicesImpl implements userSrevices{

    @Override
    public void addUser() {
      System.out.println("增長了一個用戶");

    }

    @Override
    public void deleteUser() {
      System.out.println("刪除了一個用戶");
    }

}

//測試

public class test {

public static void main(String[] args) {
  //被代理類
  userSrevices target = new userSrevicesImpl();
  //代理類
  DynamicProxy handle = new DynamicProxy(target);
  //獲取代理
  userSrevices proxy = (userSrevices)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);//Proxy類建立代理對象。
  //執行
  proxy.addUser();
  proxy.deleteUser();
}

}

Cglib動態代理:(目前還沒有有實例。。。故引用一哈別的大神的講解)http://www.javashuo.com/article/p-brwlvetb-gd.html

AspectJ實現:

 

未完待續。

相關文章
相關標籤/搜索