版權聲明:本文為 testcs_dn(微wx笑) 原創文章,非商用自由轉載-保持署名-注明出處,謝謝。 https://blog.csdn.net/testcs_dn/article/details/80225584
AOP(面向切面程式設計)
面向切面程式設計(AOP是Aspect Oriented Program的首字母縮寫) ,我們知道,面向對象的特點是繼承、多态和封裝。而封裝就要求将功能分散到不同的對象中去,這在軟體設計中往往稱為職責配置設定。實際上也就是說,讓不同的類設計不同的方法。這樣代碼就分散到一個個的類中去了。這樣做的好處是降低了代碼的複雜程度,使類可重用。
但是人們也發現,在分散代碼的同時,也增加了代碼的重複性。什麼意思呢?比如說,我們在兩個類中,可能都需要在每個方法中做日志。按面向對象的設計方法,我們就必須在兩個類的方法中都加入日志的内容。也許他們是完全相同的,但就是因為面向對象的設計讓類與類之間無法聯系,而不能将這些重複的代碼統一起來。
也許有人會說,那好辦啊,我們可以将這段代碼寫在一個獨立的類獨立的方法裡,然後再在這兩個類中調用。但是,這樣一來,這兩個類跟我們上面提到的獨立的類就有耦合了,它的改變會影響這兩個類。那麼,有沒有什麼辦法,能讓我們在需要的時候,随意地加入代碼呢?這種在運作時,動态地将代碼切入到類的指定方法、指定位置上的程式設計思想就是面向切面的程式設計。
一般而言,我們管切入到指定類指定方法的代碼片段稱為切面,而切入到哪些類、哪些方法則叫切入點。有了AOP,我們就可以把幾個類共有的代碼,抽取到一個切片中,等到需要時再切入對象中去,進而改變其原有的行為。這樣看來,AOP其實隻是OOP的補充而已。OOP從橫向上區分出一個個的類來,而AOP則從縱向上向對象中加入特定的代碼。有了AOP,OOP變得立體了。如果加上時間次元,AOP使OOP由原來的二維變為三維了,由平面變成立體了。從技術上來說,AOP基本上是通過代理機制實作的。 AOP在程式設計曆史上可以說是裡程碑式的,對OOP程式設計是一種十分有益的補充。
AOP不一定都像Spring AOP那樣,是在運作時生成代理對象來織入的,還可以在編譯期、類加載期織入,比如AspectJ。AOP像OOP一樣,隻是一種程式設計範式,AOP并沒有規定說,實作AOP協定的代碼,要用什麼方式去實作。
什麼是代理模式,就是我再生成一個代理類,去代理UserController的saveUser()方法,代碼大概就長這樣:
class UserControllerProxy {
private UserController userController;
public void saveUser() {
checkAuth();
userController.saveUser();
}
}
代理分為靜态代理和動态代理,靜态代理,顧名思義,就是你自己寫代理對象,動态代理,則是在運作期,生成一個代理對象。Spring AOP就是基于動态代理的,但是不是所有AOP的實作都是在運作時進行織入的,因為這樣效率太低了,而且隻能針對方法進行AOP,無法針對構造函數、字段進行AOP。我完全可以在編譯成class時就織入啊,比如AspectJ,當然AspectJ還提供了後編譯器織入和類加載期織入。
AOP概念
— 方面(Aspect):一個關注點的子產品化,這個關注點實作可能另外橫切多個對象。事務管理是J2EE應用中一個很好的橫切關注點例子。方面用Spring的Advisor或攔截器實作。
— 連接配接點(Joinpoint):程式執行過程中明确的點,如方法的調用或特定的異常被抛出。
— 通知(Advice):在特定的連接配接點,AOP架構執行的動作。各種類型的通知包括“around”、“before”和“throws”通知。通知類型将在下面讨論。許多AOP架構包括Spring都是以攔截器做通知模型,維護一個“圍繞”連接配接點的攔截器鍊。
— 切入點(Pointcut):指定一個通知将被引發的一系列連接配接點的集合。AOP架構必須允許開發者指定切入點,例如,使用正規表達式。
— 引入(Introduction):添加方法或字段到被通知的類。Spring允許引入新的接口到任何被通知的對象。例如,你可以使用一個引入使任何對象實作IsModified接口,來簡化緩存。
— 目标對象(Target Object):包含連接配接點的對象,也被稱作被通知或被代理對象。
— AOP代理(AOP Proxy):AOP架構建立的對象,包含通知。在Spring中,AOP代理可以是JDK動态代理或CGLIB代理。
— 編織(Weaving):組裝方面來建立一個被通知對象。這可以在編譯時完成(例如使用AspectJ編譯器),也可以在運作時完成。Spring和其他純Java AOP架構一樣,在運作時完成織入。
各種通知類型包括:
— Around通知:包圍一個連接配接點的通知,如方法調用。這是最強大的通知。Aroud通知在方法調用前後完成自定義的行為,它們負責選擇繼續執行連接配接點或通過傳回它們自己的傳回值或抛出異常來短路執行。
— Before通知:在一個連接配接點之前執行的通知,但這個通知不能阻止連接配接點前的執行(除非它抛出一個異常)。
— Throws通知:在方法抛出異常時執行的通知。Spring提供強制類型的Throws通知,是以你可以書寫代碼捕獲感興趣的異常(和它的子類),不需要從Throwable或Exception強制類型轉換。
— After returning通知:在連接配接點正常完成後執行的通知,例如,一個方法正常傳回,沒有抛出異常。
Around通知是最通用的通知類型。大部分基于攔截的AOP架構(如Nanning和Jboss 4)隻提供Around通知。
如同AspectJ,Spring提供所有類型的通知,我們推薦你使用最為合适的通知類型來實作需要的行為。例如,如果隻是需要用一個方法的傳回值來更新緩存,你最好實作一個after returning通知,而不是around通知,雖然around通知也能完成同樣的事情。使用最合适的通知類型使程式設計模型變得簡單,并能減少潛在錯誤。例如,你不需要調用在around通知中所需使用的MethodInvocation的proceed()方法,是以就調用失敗。
切入點的概念是AOP的關鍵,它使AOP差別于其他使用攔截的技術。切入點使通知獨立于OO的層次標明目标。例如,提供聲明式事務管理的around通知可以被應用到跨越多個對象的一組方法上。 是以切入點構成了AOP的結構要素。
Filter(過慮器)
Filter技術是Servlet2.3新增加的功能,Servlet2.3是sun公司于2000年10月釋出的,它的開發者包括許多個人和公司團體,充分展現了sun公司所倡導的代碼開放性原則。在衆多參與者的共同努力下,Servlet2.3比以往功能都強大了很多,而且性能也有了提高。那麼Filter有什麼功能呢?Filter可以用來設定字元集、控制權限、控制轉向等等。簡單點說:就是定義在通路某對象之前和通路之後要做的事情。
Interceptor(攔截器)
1,攔截器的概念
java裡的攔截器是動态攔截Action調用的對象,它提供了一種機制可以使開發者在一個Action執行的前後執行一段代碼,也可以在一個Action
執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分代碼的方式。在AOP中,攔截器用于在某個方法或者字段被通路之前,進行攔截
然後再之前或者之後加入某些操作。目前,我們需要掌握的主要是Spring的攔截器,Struts2的攔截器不用深究,知道即可。
2,攔截器的原理
大部分時候,攔截器方法都是通過代理的方式來調用的。Struts2的攔截器實作相對簡單。當請求到達Struts2的ServletDispatcher時,Struts2
會查找配置檔案,并根據配置執行個體化相對的攔截器對象,然後串成一個清單(List),最後一個一個的調用清單中的攔截器。Struts2的攔截器是可
插拔的,攔截器是AOP的一個實作。Struts2攔截器棧就是将攔截器按一定的順序連接配接成一條鍊。在通路被攔截的方法或者字段時,Struts2攔截器鍊
中的攔截器就會按照之前定義的順序進行調用。
3,自定義攔截器的步驟
第一步:自定義一個實作了Interceptor接口的類,或者繼承抽象類AbstractInterceptor。
第二步:在配置檔案中注冊定義的攔截器。
第三步:在需要使用Action中引用上述定義的攔截器,為了友善也可以将攔截器定義為預設的攔截器,這樣在不加特殊說明的情況下,所有的
Action都被這個攔截器攔截。
4,過濾器與攔截器的差別
過濾器可以簡單的了解為“取你所想取”,過濾器關注的是web請求;攔截器可以簡單的了解為“拒你所想拒”,攔截器關注的是方法調用,比如攔截
敏感詞彙。
4.1,攔截器是基于java反射機制來實作的,而過濾器是基于函數回調來實作的。(有人說,攔截器是基于動态代理來實作的)
4.2,攔截器不依賴servlet容器,過濾器依賴于servlet容器。
4.3,攔截器隻對Action起作用,過濾器可以對所有請求起作用。
4.4,攔截器可以通路Action上下文和值棧中的對象,過濾器不能。
4.5,在Action的生命周期中,攔截器可以多次調用,而過濾器隻能在容器初始化時調用一次。
5,Spring攔截器
5.1,抽象類HandlerInterceptorAdapter
我們如果在項目中使用了Spring架構,那麼,我們可以直接繼承HandlerInterceptorAdapter.java這個抽象類,來實作我們自己的攔截器。
Spring架構,對java的攔截器概念進行了包裝,這一點和Struts2很類似。HandlerInterceptorAdapter繼承了抽象接口HandlerInterceptor。
相關參考:
Java三大器之攔截器(Interceptor)的實作原理及代碼示例 關于 Spring AOP (AspectJ) 你該知曉的一切