1.aop是什么
那AOP通俗點來講是啥呢?
舉個例子:
現在假設系統中有 3 段完全相似的代碼,這些代碼通常會采用“復制”、“粘貼”方式來完成,通過這種“復制”、“粘貼”方式開發出來的軟件。
可能有的讀者已經發現了這種做法的不足之處:如果有一天,這部分相似的代碼段需要修改,那是不是要打開 3 個地方的代碼進行修改?
如果不是 3 個地方包含這段代碼,而是 100 個地方,甚至是 1000 個地方包含這段代碼段,那會是什么后果?
針對該情況我們會做優化:抽出這部分代碼,封裝在一個公共類的方法里,提供其他地方調用。
當這塊功能需要調整時,只要修改一個地方即可,不管整個系統中有多少地方調用了該方法,程序無須修改這些地方,只需修改被調用的方法即可——通過這種方式,大大降低了軟件后期維護的復雜度。
讀到這里你會發現,我們還沒講到AOP...下面我們再升級下場景:
如果 3 個地方需要同樣新調一個方法,我們的做法會是在這三個地方各自額外補充新方法的調用。
如果不是 3 個地方新調用,而是 100 個地方,甚至是 1000 個地方來新調用,這樣做的工作量也不小啊!
我們希望有一種特殊的方法:我們只要定義該方法,無須在方法 1、方法 2、方法 3 中顯式調用它,系統會“自動”執行該特殊方法。
上面想法聽起來很神奇,甚至有一些不切實際,但其實是完全可以實現的,實現這個需求的技術就是 AOP。
AOP 專門用於處理系統中分布於各個模塊(不同方法)中的交叉關注點的問題。
在 Java EE 應用中,常常通過 AOP 來處理一些具有橫切性質的系統級服務,如事務管理、安全檢查、緩存、對象池管理等,AOP 已經成為一種非常常用的解決方案。
咳咳,AOP概念正式版:
AOP(Aspect Orient Programming),作為面向對象編程的一種補充,廣泛應用於處理一些具有橫切性質的系統級服務,如事務管理、安全檢查、緩存、對象池管理等。
AOP 實現的關鍵就在於 AOP 框架自動創建的 AOP 代理,AOP 代理則可分為靜態代理和動態代理兩大類,其中靜態代理是指使用 AOP 框架提供的命令進行編譯,從而在編譯階段就可生成 AOP 代理類,因此也稱為編譯時增強;
而動態代理則在運行時借助於 JDK 動態代理、CGLIB 等在內存中“臨時”生成 AOP 動態代理類,因此也被稱為運行時增強。
2.有什么作用
通過AOP,可以在指定位置執行對應流程。這樣就可以將一些橫向的功能抽離出來形成一個獨立的模塊,然后在指定位置插入這些功能。
3.怎么用
下面我們整理下普通的Java代碼中怎么實現AOP:
有兩種方式實現AOP切面,一種是原生SDK實現,一種是基於三方包cglib。
(Java的有3種代理模式:靜態代理、動態代理、cglib代理。)
代理·比較
那么這兩種方式有什么相同點和區別呢?
相同點是都使用了代理模式。
不同點是前者使用了接口代理,后者使用了繼承代理。
JDK代理類是接口代理,是因為它繼承了proxy這個類,java是單繼承的,jdk代理類通過調用處理器中的invoke方法來實現動態代理的目的。
cglib是子類代理,cglib性能要比jdk好,但創建代理對象時,jdk比cglib效率高。
JDK的動態代理有一個限制,就是使用動態代理的對象必須實現一個或多個接口,如果想代理沒有實現接口的類,就可以使用Cglib實現。Cglib是一個強大的高性能的代碼生成包,它可以在運行期擴展java類與實現java接口。它廣泛的被許多AOP的框架使用它廣泛的被許多AOP的框架使用,例如Spring AOP和synaop,為他們提供方法的interception(攔截)。
Cglib包的底層是通過使用一個小而塊的字節碼處理框架ASM來轉換字節碼並生成新的類。不鼓勵直接使用ASM,因為它要求你必須對JVM內部結構包括class文件的格式和指令集都很熟悉。
總結
1、AOP 是用來處理一些具有橫切性質的系統級服務。
2、java代理有三種:靜態代理、動態代理、cglib代理。其中AOP涉及到的是后兩者。
3、JDK代理是接口代理,cglib是繼承代理(Spring aop就是用該框架)。