AOP專門用於處理系統中分佈於各個模塊(不一樣方法)中的交叉關注點的問題,在JavaEE應用中,經常經過AOP來處理一些具備橫切性質的系統級服務,如事務管理、安全檢查、緩存、對象池管理等,AOP已經成爲一種很是經常使用的解決方案。java
在學習SpringAOP以前,咱們先來簡單看看AspectJ。編程
AspectJ是一個基於Java語言的AOP框架,提供了強大的AOP功能,其餘不少AOP框架都借鑑或採納其中的一些思想。因爲Spring3.0的AOP與AspectJ進行了很好的集成,所以掌握AspectJ是學習SpringAOP的基礎。緩存
AspectJ主要包括兩個部分:安全
部分 | 描述 |
第一部分 | 定義瞭如何表達、定義AOP編程中的語法規範,經過這套規範,咱們能夠方便地用AOP來解決Java語言中存在的交叉關注點問題。框架 |
另外一部分 | 工具部分,包括編譯器、調試工具等。 |
package com.ant; public class Hello{ public static void main(String[] args){ Hello hello = new Hello(); hello.sayHello(); } public void sayHello(){ System.out.println("Hello AspectJ!"); } }
package com.ant; public aspect TxAspect{ void around():call(void Hello.sayHello()){ System.out.println("Transaction start..."); proceed(); System.out.println("Transaction end..."); } }
package com.ant; public aspect LogAspect{ pointcut logPointcut():execution(void Hello.sayHello()); after():logPointcut(){ System.out.println("log..."); } }
咱們利用javap反編譯生成的Hello.class,能夠發現它不是由Hello.java編譯獲得的,該Hello.class文件內新增了不少內容------這代表AspectJ在編譯時已經加強了Hello.class的功能,所以AspectJ一般被稱爲編譯時加強的AOP框架。工具
Compiled from "Hello.java" public class com.ant.Hello { public com.ant.Hello(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: new #1 // class com/ant/Hello 3: dup 4: invokespecial #17 // Method "<init>":()V 7: astore_1 8: aload_1 9: astore_2 10: aload_2 11: invokestatic #56 // Method com/ant/TxAspect.aspectOf:()Lcom/ant/TxAspect; 14: aconst_null 15: invokestatic #60 // Method sayHello_aroundBody1$advice:(Lcom/ant/Hello;Lcom/ant/TxAspect;Lorg/aspectj/runtime/internal/AroundClosure;)V 18: return public void sayHello(); Code: 0: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #30 // String Hello AspectJ! 5: invokevirtual #32 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: goto 20 11: astore_1 12: invokestatic #67 // Method com/ant/LogAspect.aspectOf:()Lcom/ant/LogAspect; 15: invokevirtual #70 // Method com/ant/LogAspect.ajc$after$com_ant_LogAspect$1$9fd5dd97:()V 18: aload_1 19: athrow 20: invokestatic #67 // Method com/ant/LogAspect.aspectOf:()Lcom/ant/LogAspect; 23: invokevirtual #70 // Method com/ant/LogAspect.ajc$after$com_ant_LogAspect$1$9fd5dd97:()V 26: return Exception table: from to target type 0 11 11 Class java/lang/Throwable private static final void sayHello_aroundBody0(com.ant.Hello); Code: 0: aload_0 1: invokevirtual #18 // Method sayHello:()V 4: return private static final void sayHello_aroundBody1$advice(com.ant.Hello, com.ant.TxAspect, org.aspectj.runtime.internal.AroundClosure); Code: 0: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #44 // String Transaction start... 5: invokevirtual #32 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: aload_2 9: astore_3 10: aload_0 11: invokestatic #62 // Method sayHello_aroundBody0:(Lcom/ant/Hello;)V 14: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 17: ldc #52 // String Transaction end... 19: invokevirtual #32 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 22: return }
與AspectJ相對的還有另一種AOP框架,它們不須要在編譯時對目標類進行加強,而是運行時生成目標類的代理類,該代理類要麼與目標類實現相同的接口,要麼是目標類的子類------總之,代理類都對目標類進行了加強處理,前者是JDK動態代理的處理策略,後者是cglib代理的處理策略。SpringAOP以建立動態代理的方式來生成代理類,底層既可以使用JDK動態代理,也可採用cglib代理。學習