面向切面編程(AOP)及其作用


在OOP設計中,它導致了大量代碼的重復,而不利於各個模塊的重用。

1、面向切面編程(AOP)

  面向切面編程(AOP)就是對軟件系統不同關注點的分離,開發者通過攔截方法調用並在方法調用前后添加輔助代碼。

  AOP利用一種稱為“橫切”的技術,剖解開封裝的對象內部,並將那些影響了多了類的公共行為封裝到一個可重用的模塊,並將其命名為“Aspect”,即切面。

  所謂“切面”,簡單地說,就是將那些於業務無關,卻為月舞模塊所共同調用的邏輯或責任封裝起來。

  切面就是橫切面,代表的是一個普遍存在的共有功能。

  AOP代表的是一個橫向關系

  AOP吧軟件系統分為兩個部分:核心關注點和橫切關注點。

  業務出路的主要流程是核心關注點,與之關系不大的部分是橫切關注點。

  橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處都基本相似。比如權限認證、日志、事務處理。

2、AOP的作用在與分離系統中各個關注點,將核心關注點和橫切關注點分離開來。

java代碼:

public class BusinessLogic{

  public voidSomeOPration(){

    //日志記錄;

    //權限驗證;

    DoSomething();

    //失誤控制;

  }

}

3、AOP技術的實現

AOP技術是建立在JAVA語言的反射機制與動態代理機制之上的。

業務邏輯組件在運行過程中,AOP容器動態創建一個代理對象供使用者調用。該代理對象已經按程序員的意圖將切面成功切入到目標方法的連接點上,從而切面的功能與業務邏輯的功能同時的以執行。

AOP是一種編程概念,因此他並未綁定帶任何特定的語言。事實上,他對所有單獨的、垂直的分解式(AOP通常被認為是橫向分解)的語言(不僅是OO語言)都有幫助。AOP在不同語言都有實現(如C++,Smalltalk,C#,C,Java)。

4、攔截器的設計原理

  Struts2.0的攔截器的設計體現了一種編程的設計理念,即面向切面編程AOP。

  攔截是AOP的一種實現策略,在AOP中某個方法或字段被訪問,可以進行攔截,然后在其之前或其之后加入某些操作。

5、什么是攔截器(Interceptor)?

  攔截器是動態攔截Action調用的對象。他提供了中機制是開發者可以在一個Action執行之前或執行之后插入需要的代碼。

6、理解DRY(Don't Repeat Yourself)規則

  在軟件開發領域,有一個非常重要的規則:Don't Repeat Yourself,就是所謂的DRY規則,意思就是不要寫重復代碼。

為什么要使用方法調用呢?而不是在三個地方使用重復的代碼呢?

  很多初學者認為是為了編程的簡單,代碼簡潔。實際上,這是次要的,最重要的原因是為了軟件后期的升級及維護。

7、攔截器的意義

  攔截器是對調用方法的改進。我們說某個實例是一個攔截器時,這是從行為上來說的,如果從代碼的角度來看,攔截器也是一個類,類中包含有方法,知識這個方法比較特殊,他會在目標方法調用之前“自動”執行。

  進一步改進,如圖:

作用:(1)提供可更高層次的解耦

    (2)允許改變被調用方法的方法體

    (3)可以改變調用的目標方法

8、實現原理

  如何自動的調用攔截器,而且知道到底調用呢個攔截器的方法?大部分的時候,攔截器方法都是通過JDK的動態代理來調用的,AOP的實現機制。

9、攔截器在Struts2.0中的角色

  

作用:(1)攔截器是通過struts.xml文件配置的,從而實現了對Action通用操作的可插撥式管理。

  (2)降低了Action與特定代碼的耦合性

  (3)提高了ACtion的復用性

  (4)吧多個Action中需要重復指定的代碼取出,放在攔截器類中定義,從而提供更好地代碼重用。

10、Struts2中的攔截器

  在Struts2中已經在struts-default.xml中預定義了一些自帶的攔截器,如timer、params等。

  如果在struts.xml中配置<package>標簽中繼承struts-default,則當前package就會自動擁有struts-default.xml中的所有配置。代碼如下:

  

<package name="xxx" extends="struts-default" > ... </package>

11、攔截器的定義

  在struts.xml文件中定義攔截器語法格式:

  <interceptor name="攔截器名" class=“攔截器實現類/”>

12、應用定義好的攔截器

  <interceptor-ref name="攔截器名/">

在struts-default.xml中有一個默認的引用,在默認情況下(也就是<action>中未引用攔截器時)會自動引用一些攔截器。

  <default-interceptor-ref name="defaultStack/">

上面在defaultStack中引用的攔截器都可以<action>中不經過引用可以使用

注意:如果在<action>中引用了任何攔截器后,要使用在defaultStack中定義的攔截器,需要在<action>中重新引用。

13、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攔截器已經不起作用了。

14、使用攔截器棧

為了能在多個動作中方便的引用同一個或幾個攔截器,可以使用攔截器棧將這些攔截器當個整體來引用。

攔截器棧要在<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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM