在OOP設計中,它致使了大量代碼的重複,而不利於各個模塊的重用。java
一、面向切面編程(AOP)程序員
面向切面編程(AOP)就是對軟件系統不一樣關注點的分離,開發者經過攔截方法調用並在方法調用先後添加輔助代碼。編程
AOP利用一種稱爲「橫切」的技術,剖解開封裝的對象內部,並將那些影響了多了類的公共行爲封裝到一個可重用的模塊,並將其命名爲「Aspect」,即切面。服務器
所謂「切面」,簡單地說,就是將那些於業務無關,卻爲月舞模塊所共同調用的邏輯或責任封裝起來。jsp
切面就是橫切面,表明的是一個廣泛存在的共有功能。測試
AOP表明的是一個橫向關係spa
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中配置<package>標籤中繼承struts-default,則當前package就會自動擁有struts-default.xml中的全部配置。代碼以下:
<package name="xxx" extends="struts-default" > ... </package>
十一、攔截器的定義
在struts.xml文件中定義攔截器語法格式:
<interceptor name="攔截器名" class=「攔截器實現類/」>
十二、應用定義好的攔截器
<interceptor-ref name="攔截器名/">
在struts-default.xml中有一個默認的引用,在默認狀況下(也就是<action>中未引用攔截器時)會自動引用一些攔截器。
<default-interceptor-ref name="defaultStack/">
上面在defaultStack中引用的攔截器均可以<action>中不通過引用可使用
注意:若是在<action>中引用了任何攔截器後,要使用在defaultStack中定義的攔截器,須要在<action>中從新引用。
1三、params攔截器使用
當客戶端的一個form想服務器端提交請求時,若有textfield,代碼以下:
<s:form action="login" >
username <s:textfield name="username"/> <br>
password <s:password name="password" /> <br>
<s:submit/>
</s:form>
在提交後,Struts2將會自動調用login動做類中的setXX方法,並將文本框中的值經過setXXX方法的參數傳入。
實際上,這個操做是由params攔截器完成的,params對應的類是com.opensymphony.xwork2.interception.Parameterslnterceptor.
因爲params已經在defaultStack中定義,所以,在未引用攔截器的<action>中是會自動引用params的。
以下面的配置代碼,在訪問login動做時,Struts是會自動執行相應的setter方法的。
<action name="login" class=「com.ascent.action.LoginAction"> <result>/success.jsp</result>
<result name="input">/login.jsp</result>
</action>
這樣,登錄表單中的用戶名,密碼參數就會在Action類中被set進去,完成登錄功能。
但若是在<action>中引用了其餘攔截器,就必須顯示的引用params攔截器,Struts2不能調用相應的setter方法來初始化參數。以下面的配置代碼所示:
<action name="login" class=「com.ascent.action.LoginAction">
<interceptor-ref name="timer" />
<interceptor-ref name="logger"/>
<interceptor-ref name="params"/>
<result>/success.jsp</result>
<result name="input">/login.jsp</result>
</action>
咱們能夠不去配置params攔截器,配置timer和logger或任意一個,測試參數username、password的值,應該是沒有獲得表單提交的值,由於params攔截器已經不起做用了。
1四、使用攔截器棧
爲了能在多個動做中方便的引用同一個或幾個攔截器,可使用攔截器棧將這些攔截器當個總體來引用。
攔截器棧要在<package>標籤中使用<interceptors>和子標籤<interceptor-stack>來定能夠像使用攔截器同樣使用攔截器棧。
<package name="demo" extends="struts-default" >
<interceptors>
<interceptor-stack name="mystack">
<interceptor-ref name="timer" />
<interceptor-ref name="logger" />
<interceptor-ref name="params" />
</interceptor-stack>
</interceptors>
<action name="login" class="com.ascent.action.LoginAction">
<interceptor-ref name="mystack"/>
</action>
</package>