AOP概念及術語

====關注點(Concern)====
關注點就是我們要考察或解決的問題。如訂單的處理,用戶的驗證、用戶日誌記錄等都屬於關注點。
 
關注點中的核心關注點(Core Concerns),是指系統中的核心功能,即真正的商業邏輯。如在一個電子商務系統中,訂單處理、客戶管理、庫存及物流管理都是屬於系統中的核心關注點。
 
還有一種關注點叫橫切關注點 (Crosscutting Concerns),他們分散在每個各個模塊中解決同一樣的問題,跨越多個模塊。如用戶驗證、日誌管理、事務處理、數據緩存都屬於橫切關注點。
 
在AOP的編程方法中,主要在於對關注點的提起及抽象。我們可以把一個複雜的系統看作是由多個關注點來有機組合來實現,一個典型的系統可能會包括幾個方面的關注點,如核心業務邏輯、性能、數據存儲、日誌、授權、安全、線程及錯誤檢查等,另外還有開發過程中的關注點,如易維護、易擴展等。  
 
====切面(Aspect) ====
 
切面是一個關注點的模塊化,這個關注點可能會橫切多個對象和模塊,事務管理是橫切關注點的很好的例子。它是一個抽象的概念,從軟件的角度來說是指在應用程序不同模塊中的某一個領域或方面。
在Spring 2.0 AOP中,切面可以使用基於XML Schema的風格或者以 @Aspect註解(@AspectJ風格)來實現
 
下面的例子是基於xml schema風格來定義一個Aspect(紅字部分):
<aop:aspect id="aspectDemo" ref="aspectBean">
<aop:pointcut id="myPointcut"
expression="execution(* package1.Foo.handle*(..)"/>
<aop:before pointcut-ref="myPointcut" method="doLog" />
</aop:aspect>
 
這個定義的意思是:每執行到package1.Foo類的以handle開頭的方法前,就會先執行aspectBean的doLog方法
 
 
====連接點(Join point) ====
 
連接點就是在程序執行過程中某個特定的點,比如某方法調用的時候或者處理異常的時候。這個點可以是一個方法、一個屬性、構造函數、類靜態初始化塊,甚至一條語句。而對於SPRING 2.0 AOP來說,連接點只能是方法,這個一定要記住~!每一個方法都可以看成爲一個連接點,只有被納入某個CutPoint的JointPoint纔有可能被Advice。
 
通過聲明一個org.aspectj.lang.JoinPoint類型的參數可以使通知(Advice)的主體部分獲得連接點信息。
 
JoinPoint與CutPoint之間的關係見下面的CutPoint的講解
 
====切入點(Pointcuts) ====
切入點指一個或多個連接點,可以理解成連接電點的集合. Advice是通過Pointcut來連接和介入進你的JointPoint的。
 
比如在前面的例子中,定義了
<aop:pointcut id="myPointcut"
expression="execution(* package1.Foo.handle*(..)"/>
那麼這就是定義了一個PointCut,該Pointcut表示“在package1.Foo類所有以handle開頭的方法”
假設package1.Foo類裏類似於:
    Public class Foo{
       public handleUpload(){..}
       public handleReadFile(){..}
       .....
    }
那麼handleUpload是一個JointPoint,handleReadFile也是一個Joint,那麼上面定義的id=”myPointcut”的PointCut則是這兩個JointPoint的集合
 
====通知(Advice) ====
Advice定義了切面中的實際邏輯(即實現),比如日誌的寫入的實際代碼。換一種說法Advice是指在定義好的切入點處,所要執行的程序代碼。(在Join Point上執行的一個動作) 
通知有以下幾種:
前置通知(Before advice):在切入點匹配的方法執行之前運行使用@Before註解來聲明
 
返回後通知(After returning advice):在切入點匹配的方法返回的時候執行。使用 @AfterReturning註解來聲明
 
拋出後通知(After throwing advice): 在切入點匹配的方法執行時拋出異常的時候運行。使用 @AfterThrowing 註解來聲明
 
後通知(After (finally) advice):不論切入點匹配的方法是正常結束的,還是拋出異常結束的,在它結束後(finally)後通知(After (finally) advice)都會運行。使用 @After註解來聲明。這個通知必須做好處理正常返回和異常返回兩種情況。通常用來釋放資源。
 
環繞通知(Around Advice):環繞通知既在切入點匹配的方法執行之前又在執行之後運行。並且,它可以決定這個方法在什麼時候執行,如何執行,甚至是否執行。在環繞通知中,除了可以自由添加需要的橫切功能以外,還需要負責主動調用連接點(通過proceed)來執行激活連接點的程序。 請儘量使用最簡單的滿足你需求的通知。(比如如果前置通知也可以適用的情況下,就不要使用環繞通知)
 
環繞通知使用 @Around 註解來聲明。而且該通知對應的方法的第一個參數必須是ProceedingJoinPoint 類型。在通知體內(即通知的具體方法內),調用 ProceedingJoinPoint 的 proceed() 方法來執行連接點方法。
 
 
====引入(Introduction) ====
引入是指給一個現有類添加方法或字段屬性,引入還可以在不改變現有類代碼的情況下,讓現有的Java類實現新的接口(以及一個對應的實現)。相對於Advice可以動態改變程序的功能或流程來說,引介(Introduction)則用來改變一個類的靜態結構。比如你可以使用一個引入來使bean實現 IsModified 接口,以便簡化緩存機制
 
 
====目標對象(Target Object)====
被一個或者多個切面(aspect)所通知(advise)的對象。也有人把它叫做 被通知(advised) 對象。 既然Spring AOP是通過運行時代理實現的,這個對象永遠是一個 被代理(proxied)對象。(包含Join Point的對象,也就是被就Advice的類,也就是是商務邏輯對象,比如銀行櫃員機類。這個對象永遠是一個被代理的對象。)
 
 
====AOP代理(AOP Proxy)====
AOP框架創建的對象,用來實現切面契約(aspect contract)(包括通知方法執行等功能)。 在Spring中,AOP代理可以是JDK動態代理或者CGLIB代理。注意:Spring 2.0最新引入的基於模式(schema-based)風格和@AspectJ註解風格的切面聲明,對於使用這些風格的用戶來說,AOP代理的創建是透明的。
 
Spring缺省使用J2SE 動態代理(dynamic proxies)來作爲AOP的代理。這樣任何接口都可以被代理。
Spring也支持使用CGLIB代理. 對於需要代理類而不是代理接口的時候CGLIB代理是很有必要的。 如果一個業務對象並沒有實現一個接口,默認就會使用CGLIB。 作爲面向接口編程的最佳實踐,業務對象通常都會實現一個或多個接口。
====織入(Weaving)====
把切面(aspect)連接到其它的應用程序類型或者對象上,並創建一個被通知(advised)的對象,這樣一個行爲就叫做Weaving。 這些可以在編譯時(例如使用AspectJ編譯器),類加載時和運行時完成。 Spring和其他純Java AOP框架一樣,在運行時完成織入。
 
其實織入的方式有3種:
1、運行時織入-即在java運行的過程中,使用Java提供代理來實現織入。根據代理產生方式的不同,運行時織入又可以進一步分爲J2SE動態代理及動態字節碼生成兩種方式。由於J2SE動態代理只能代理接口,因此,需要藉助於一些動態字節碼生成器來實現對類的動態代理。大多數AOP實現都是採用這種運行時織入的方式,包括Spring。
 
2、類加載器織入-指通過自定義的類加載器,在虛擬機JVM加載字節碼的時候進行織入,比如AspectWerkz(已併入AspecJ)及JBoss就使用這種方式。
 
3、編譯器織入-使用專門的編譯器來編譯包括切面模塊在內的整個應用程序,在編譯的過程中實現織入,這種織入是功能最強大的。編譯器織入的AOP實現一般都是基於語言擴展的方式,即通過對標準java語言進行一些簡單的擴展,加入一些專用於處理AOP模塊的關鍵字,定義一套語言規範,通過這套語言規範來開發切面模塊,使用自己的編譯器來生成java字節碼。AspectJ主要就是是使用這種織入方式。

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/totogogo/archive/2007/04/24/1583152.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章