Aspect Oriented Programming(AOP)是較爲熱門的一個話題。AOP,國內大體譯做「面向切面編程」。java
日誌記錄,性能統計,安全控制,事務處理,異常處理等等wn及擴展程序員
將日誌記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯代碼中劃分出來,經過對這些行爲的分離,咱們但願能夠將它們獨立到非指導業務邏輯的方法中,進而改變這些行爲的時候不影響業務邏輯的代碼。arkdown Extra** 定義列表語法:spring
假設在一個應用系統中,有一個共享的數據必須被併發同時訪問,首先,將這個數據封裝在數據對象中,稱爲Data Class,同時,將有多個訪問類,專門用於在同一時刻訪問這同一個數據對象。
爲了完成上述併發訪問同一資源的功能,須要引入鎖Lock的概念,也就是說,某個時刻,當有一個訪問類訪問這個數據對象時,這個數據對象必須上鎖Locked,用完後就當即解鎖unLocked,再供其它訪問類訪問。
使用傳統的編程習慣,咱們會建立一個抽象類,全部的訪問類繼承這個抽象父類,以下:
abstract class Worker {
abstract void locked();
abstract void accessDataObject();
abstract void unlocked();
}
accessDataObject()方法須要有「鎖」狀態之類的相關代碼。數據庫
Java只提供了單繼承,所以具體訪問類只能繼承這個父類,若是具體訪問類還要繼承其它父類,好比另一個如Worker的父類,將沒法方便實現。編程
重用被打折扣,具體訪問類由於也包含「鎖」狀態之類的相關代碼,只能被重用在相關有「鎖」的場合,重用範圍很窄。設計模式
仔細研究這個應用的「鎖」,它其實有下列特性:
「鎖」功能不是具體訪問類的首要或主要功能,訪問類主要功能是訪問數據對象,例如讀取數據或更改動做。
「鎖」緩存
「鎖」功能實際上是這個系統的一個縱向切面,涉及許多類、許多類的方法。如上圖:安全
`所以,一個新的程序結構應該是關注系統的縱向切面,例如這個應用的「鎖」功能,這個新的程序結構就是aspect(方面) 在這個應用中,「鎖」方面(aspect)應該有如下職責:` * 1 * 2
提供一些必備的功能,對被訪問對象實現加鎖或解鎖功能。以保證全部在修改數據對象的操做以前可以調用lock()加鎖,在它使用完成後,調用unlock()解鎖。性能優化
很明顯,AOP很是適合開發J2EE容器服務器,JBoss 4.0正是使用AOP框架進行開發。
具體功能以下:
Authentication 權限
Caching緩存
Context passing內容傳遞
Error handling 錯誤處理
Lazy loading 延時加載
Debugging 調試
logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準
Performance optimization性能優化
Persistence 持久化
Resource pooling資源池
Synchronization 同步
Transactions事務
【AOP有必要嗎?】服務器
`固然,上述應用範例在沒有使用AOP狀況下,也獲得瞭解決,例如JBoss 3.XXX也提供了上述應用功能,而且沒有使用AOP。 可是,使用AOP可讓咱們從一個更高的抽象概念來理解軟件系統,AOP也許提供一種有價值的工具。能夠這麼說:由於使用AOP結構,JBoss 4.0的源碼要比JBoss 3.X容易理解多了,這對於一個大型複雜系統來講是很是重要的。 從另一個方面說,好像不是全部的人都須要關心AOP,它多是一種架構設計的選擇,若是選擇J2EE系統,AOP關注的上述通用方面都已經被J2EE容器實現了,J2EE應用系統開發者可能須要更多地關注行業應用方面aspect。 傳統的程序一般表現出一些不能天然地適合單一的程序模塊或者是幾個緊密相關的程序模塊的行爲,AOP 將這種行爲稱爲橫切,它們跨越了給定編程模型中的典型職責界限。橫切行爲的實現都是分散的,軟件設計師會發現這種行爲難以用正常的邏輯來思考、實現和更改。最多見的一些橫切行爲以下面這些:` * 1 * 2 * 3 * 4 * 5 * 6 * 7
一、日誌記錄,跟蹤,優化和監控
二、事務的處理
三、持久化
四、性能的優化
五、資源池,如數據庫鏈接池的管理
六、系通通一的認證、權限管理等
七、應用系統的異常捕捉及處理
八、針對具體行業應用的橫切行爲
`前面幾種橫切行爲都已經獲得了密切的關注,也出現了各類有價值的應用,但也許從此幾年,AOP 對針對具體行業應用的貢獻會成爲使人關注的焦點。` * 1
AOP是一個概念,並無設定具體語言的實現,它能克服那些只有單繼承特性語言的缺點(如Java),AOP具體實現有如下幾個項目:
→AspectJ (TM): 建立於Xerox PARC. 有近十年曆史,成熟;
→缺點:過於複雜;破壞封裝;須要專門的Java編譯器;
→動態AOP:使用JDK的動態代理API或字節碼Bytecode處理技術;
→基於動態代理API的具體項目有:
JBoss 4.0 JBoss 4.0服務器;
→基於字節碼的項目有:
aspectwerkz ,spring。
`面向過程編程離咱們已經有些遙遠,面向對象編程正主宰着軟件世界。當每一個新的軟件設計師都被要求掌握如何將需求功能轉化成一個個類,而且定義它們的數據成員、行爲,以及它們之間複雜的關係的時候,面向切面編程(Aspect-Oriented Programming,AOP)爲咱們帶來了新的想法、新的思想、新的模式。 若是說面向對象編程是關注將需求功能劃分爲不一樣的而且相對獨立,封裝良好的類,並讓它們有着屬於本身的行爲,依靠繼承和多態等來定義彼此的關係的話;那麼面向切面編程則是但願可以將通用需求功能從不相關的類當中分離出來,可以使得不少類共享一個行爲,一旦發生變化,沒必要修改不少類,而只須要修改這個行爲便可。 面向切面編程是一個使人興奮不已的新模式。就開發軟件系統而言,它的影響力必將會和有着數十年應用歷史的面向對象編程同樣巨大。面向切面編程和麪向對象編程不但不是互相競爭的技術並且彼此仍是很好的互補。面向對象編程主要用於爲同一對象層次的公用行爲建模。 它的弱點是將公共行爲應用於多個無關對象模型之間。而這偏偏是面向切面編程適合的地方。有了 AOP,咱們能夠定義交叉的關係,並將這些關係應用於跨模塊的、彼此不一樣的對象模型。AOP 同時還可讓咱們層次化功能性而不是嵌入功能性,從而使得代碼有更好的可讀性和易於維護。它會和麪向對象編程合做得很好。` * 1 * 2 * 3 * 4 * 5 * 6 * 7
在OOP設計中,它致使了大量代碼的重複,而不利於各個模塊的重用。
一、面向切面編程(AOP)
面向切面編程(AOP)就是對軟件系統不一樣關注點的分離,開發者經過攔截方法調用並在方法調用先後添加輔助代碼。
AOP利用一種稱爲「橫切」的技術,剖解開封裝的對象內部,並將那些影響了多了類的公共行爲封裝到一個可重用的模塊,並將其命名爲「Aspect」,即切面。
所謂「切面」,簡單地說,就是將那些於業務無關,卻爲月舞模塊所共同調用的邏輯或責任封裝起來。
①切面就是橫切面,表明的是一個廣泛存在的共有功能。
②AOP表明的是一個橫向關係
③AOP吧軟件系統分爲兩個部分:核心關注點和橫切關注點。
④業務出路的主要流程是核心關注點,與之關係不大的部分是橫切關注點。
橫切關注點的一個特色是,他們常常發生在覈心關注點的多處,而各處都基本類似。好比權限認證、日誌、事務處理。
二、AOP的做用在與分離系統中各個關注點,將核心關注點和橫切關注點分離開來。
java代碼:
public class BusinessLogic{
public voidSomeOPration(){
//日誌記錄;
//權限驗證;
DoSomething();
//失誤控制;
}
}
三、AOP技術的實現
AOP技術是創建在JAVA語言的反射機制與動態代理機制之上的。
業務邏輯組件在運行過程當中,AOP容器動態建立一個代理對象供使用者調用。該代理對象已經按程序員的意圖將切面成功切入到目標方法的鏈接點上,從而切面的功能與業務邏輯的功能同時的以執行。
AOP是一種編程概念,所以他並未綁定帶任何特定的語言。事實上,他對全部單獨的、垂直的分解式(AOP一般被認爲是橫向分解)的語言(不只是OO語言)都有幫助。AOP在不一樣語言都有實現(如C++,Smalltalk,C#,C,Java)。
四、攔截器的設計原理
Struts2.0的攔截器的設計體現了一種編程的設計理念,即面向切面編程AOP。
攔截是AOP的一種實現策略,在AOP中某個方法或字段被訪問,能夠進行攔截,而後在其以前或其以後加入某些操做。
五、什麼是攔截器(Interceptor)?
攔截器是動態攔截Action調用的對象。他提供了中機制是開發者能夠在一個Action執行以前或執行以後插入須要的代碼。
六、理解DRY(Don’t Repeat Yourself)規則
在軟件開發領域,有一個很是重要的規則:Don’t Repeat Yourself,就是所謂的DRY規則,意思就是不要寫重複代碼。
爲何要使用方法調用呢?而不是在三個地方使用重複的代碼呢?
不少初學者認爲是爲了編程的簡單,代碼簡潔。實際上,這是次要的,最重要的緣由是爲了軟件後期的升級及維護。
七、攔截器的意義
攔截器是對調用方法的改進。咱們說某個實例是一個攔截器時,這是從行爲上來講的,若是從代碼的角度來看,攔截器也是一個類,類中包含有方法,知識這個方法比較特殊,他會在目標方法調用以前「自動」執行。
進一步改進,以下:
做用: (1)提供可更高層次的解耦
(2)容許改變被調用方法的方法體
(3)能夠改變調用的目標方法
八、實現原理
如何自動的調用攔截器,並且知道到底調用呢個攔截器的方法?大部分的時候,攔截器方法都是經過JDK的動態代理來調用的,AOP的實現機制。
九、攔截器在Struts2.0中的角色
做用:(1)攔截器是經過struts.xml文件配置的,從而實現了對Action通用操做的可插撥式管理。
(2)下降了Action與特定代碼的耦合性
(3)提升了ACtion的複用性
(4)吧多個Action中須要重複指定的代碼取出,放在攔截器類中定義,從而提供更好地代碼重用。
十、Struts2中的攔截器
在Struts2中已經在struts-default.xml中預約義了一些自帶的攔截器,如timer、params等。
若是在struts.xml中配置標籤中繼承struts-default,則當前package就會自動擁有struts-default.xml中的全部配置。代碼以下:
十一、攔截器的定義
在struts.xml文件中定義攔截器語法格式:
十二、應用定義好的攔截器
在struts-default.xml中有一個默認的引用,在默認狀況下(也就是未引用攔截器時)會自動引用一些攔截器。
上面在defaultStack中引用的攔截器均可以不通過引用可使用
注意:若是在引用了任何攔截器後,要使用在defaultStack中定義的攔截器,須要從新引用。
1三、params攔截器使用
當客戶端的一個form想服務器端提交請求時,若有textfield,代碼以下:
在提交後,Struts2將會自動調用login動做類中的setXX方法,並將文本框中的值經過setXXX方法的參數傳入。
實際上,這個操做是由params攔截器完成的,params對應的類是com.opensymphony.xwork2.interception.Parameterslnterceptor.
因爲params已經在defaultStack中定義,所以,在未引用攔截器的是會自動引用params的。
以下面的配置代碼,在訪問login動做時,Struts是會自動執行相應的setter方法的。
這樣,登錄表單中的用戶名,密碼參數就會在Action類中被set進去,完成登錄功能。
但若是在action中引用了其餘攔截器,就必須顯示的引用params攔截器,Struts2不能調用相應的setter方法來初始化參數。以下面的配置代碼所示:
咱們能夠不去配置params攔截器,配置timer和logger或任意一個,測試參數username、password的值,應該是沒有獲得表單提交的值,由於params攔截器已經不起做用了。
1四、使用攔截器棧
爲了能在多個動做中方便的引用同一個或幾個攔截器,可使用攔截器棧將這些攔截器當個總體來引用。
攔截器棧要在 package 標籤中使用 interceptors 和子標籤interceptor-stack來定能夠像使用攔截器同樣使用攔截器棧。