AspectJ初解

2006/10/30
AspectJ入門 AspectJ入門
入門-利用Eclipse編譯AspectJ入門-利用Eclipse編譯AspectJ
http://www.matrix.org.cn/resource/article/44/44423_Eclipse+AspectJ.html
如何使用AspectJ Compiler開發AspectJ程式如何使用AspectJ Compiler開發AspectJ程式
http://swanky.hsiao.googlepages.com/aspectj-with-ajc


以下出處: http://www-128.ibm.com/developerworks/cn/java/l-aspectJ/以下出處: http://www-128.ibm.com/developerworks/cn/java/l-aspectJ/
1. 序: 1.序:
AspectJ是一個代碼生成工具(Code Generator)。 AspectJ是一個代碼生成工具(Code Generator)。
AspectJ語法就是用來定義代碼生成規則的語法。 AspectJ語法就是用來定義代碼生成規則的語法。 您如果使用過Java Compiler Compiler (JavaCC),您會發現,兩者的代碼生成規則的理念驚人相似。您如果使用過Java Compiler Compiler (JavaCC),您會發現,兩者的代碼生成規則的理念驚人相似。
AspectJ有自己的語法編譯工具,編譯的結果是Java Class文件,運行的時候,classpath需要包含AspectJ的一個jar文件(Runtime lib)。 AspectJ有自己的語法編譯工具,編譯的結果是Java Class文件,運行的時候,classpath需要包含AspectJ的一個jar文件(Runtime lib)。

2. Aspect Oriented Programming (AOP) 2. Aspect Oriented Programming (AOP)
class Bank class Bank
{
public float deposit(AccountInfo account, float money) public float deposit(AccountInfo account, float money)
{
// 驗證account是否為合法用戶 // Begin Transaction //驗證account是否爲合法用戶// Begin Transaction
// 增加account賬戶的錢數,返回賬戶裡當前的錢數 // End Transaction //增加account賬戶的錢數,返回賬戶裏當前的錢數// End Transaction
}

public float withdraw(AccountInfo account, float money) public float withdraw(AccountInfo account, float money)
{
// 驗證account是否為合法用戶 // Begin Transaction //驗證account是否爲合法用戶// Begin Transaction
// 減少account賬戶的錢數,返回取出的錢數 // End Transaction //減少account賬戶的錢數,返回取出的錢數// End Transaction
}
};
以上程式內含有商業邏輯和與系統無關的邏輯(驗證),程式碼不單單只負責一件事情,增加複雜度,減少可用性.而認證,事務等方面,就是AOP所關心的Aspect。以上程式內含有商業邏輯和與系統無關的邏輯(驗證),程式碼不單單隻負責一件事情,增加複雜度,減少可用性.而認證,事務等方面,就是AOP所關心的Aspect。 AOP就是為瞭解決這種問題而出現的。 AOP就是爲了解決這種問題而出現的。 AOP的目的就是--Separation of Aspects (or Separation of Concerns). AOP的目的就是--Separation of Aspects (or Separation of Concerns).

3.AspectJ
使用AspectJ,我們不用對原有的代碼做任何修改,就可以為代碼提供不同的Aspect(方面)--比如,認證,事務等。使用AspectJ,我們不用對原有的代碼做任何修改,就可以爲代碼提供不同的Aspect(方面)--比如,認證,事務等。 我們只需要提供兩個不同的Aspect--認證Aspect和事務Aspect。我們只需要提供兩個不同的Aspect--認證Aspect和事務Aspect。
Code 4.1 AuthAspect.java Code 4.1 AuthAspect.java
aspect AuthAspect aspect AuthAspect
{
pointcut bankMethods() : execution (* Bank.deposit(…)) || execution (* Bank. withdraw (…)); pointcut bankMethods() : execution (* Bank.deposit(…)) || execution (* Bank. withdraw (…));

Object around(): bankMethods() Object around(): bankMethods()
{
// 驗證account是否為合法用戶 //驗證account是否爲合法用戶

return proceed(); return proceed();
}
};

Code 4.2 TransactionAspect.java Code 4.2 TransactionAspect.java
aspect TransactionAspect aspect TransactionAspect
{
pointcut bankMethods() : execution(* Bank.deposit(…)) || execution (* Bank. withdraw (…)); pointcut bankMethods() : execution(* Bank.deposit(…)) || execution (* Bank. withdraw (…));

Object around(): bankMethods() Object around(): bankMethods()
{
// Begin Transaction // Begin Transaction
Object result = proceed(); Object result = proceed();
// End Transaction // End Transaction
return result; return result;
}
};
這些aspect的定義,不過是定義了一些代碼生成規則。這些aspect的定義,不過是定義了一些代碼生成規則。
我們來看看,AspectJ編譯器為我們做了什麼事情。我們來看看,AspectJ編譯器爲我們做了什麼事情。

1. 首先,AspectJ從文件列表裡取出所有的文件名,然後讀取這些文件,進行分析。 1.首先,AspectJ從文件列表裏取出所有的文件名,然後讀取這些文件,進行分析。
2. AspectJ發現一些文件含有aspect的定義,在這個例子裡,就是AuthAspect和TransactionAspect的定義;這些aspect就是代碼生成規則。 2. AspectJ發現一些文件含有aspect的定義,在這個例子裏,就是AuthAspect和TransactionAspect的定義;這些aspect就是代碼生成規則。
3. AspectJ根據這些aspect代碼生成規則,修改添加你的源代碼。 3. AspectJ根據這些aspect代碼生成規則,修改添加你的源代碼。 在這個例子裡,就是修改添加Bank文件。在這個例子裏,就是修改添加Bank文件。
4. AspectJ 讀取AuthAspect的定義,發現了一個pointcut--bankMethods();這個pointcut的定義是execution(* Bank.deposit(…)) || execution(* Bank. withdraw (…)),表示所有對Bank類的deposit和withdraw方法的執行點。 4. AspectJ讀取AuthAspect的定義,發現了一個pointcut--bankMethods();這個pointcut的定義是execution(* Bank.deposit(…)) || execution(* Bank. withdraw (…)),表示所有對Bank類的deposit和withdraw方法的執行點。
5. AspectJ繼續讀取AuthAspect的定義,發現了一個around(),這在AspectJ中叫做Advice,我不明白為什麼叫這個名字,不過沒關係,我們只要知道它是幹什麼的就行了。 5. AspectJ繼續讀取AuthAspect的定義,發現了一個around(),這在AspectJ中叫做Advice,我不明白爲什麼叫這個名字,不過沒關係,我們只要知道它是幹什麼的就行了。 Advice允許你在某個類的方法的調用之前或調用之後,加入另外的代碼。 Advice允許你在某個類的方法的調用之前或調用之後,加入另外的代碼。 Code 4.1所示代碼中的around()的" // 驗證account是否為合法用戶"部分,就是要加入的代碼。 Code 4.1所示代碼中的around()的" //驗證account是否爲合法用戶"部分,就是要加入的代碼。 這段代碼要加在哪裡呢?這段代碼要加在哪裏呢? around()後面跟了一個pointcut-- bankMethods()。 around()後面跟了一個pointcut-- bankMethods()。 根據這個pointcut,AspectJ會把這段代碼加入到Bank.deposit和Bank.withdraw兩個方法的執行之前。根據這個pointcut,AspectJ會把這段代碼加入到Bank.deposit和Bank.withdraw兩個方法的執行之前。 達到的效果就如同Code 2.2所示。達到的效果就如同Code 2.2所示。
6. AspectJ讀取TransactionAspect的定義,象第(4)步一樣,發現了發現了一個pointcut--bankMethods()。 6. AspectJ讀取TransactionAspect的定義,象第(4)步一樣,發現了發現了一個pointcut--bankMethods()。
7. AspectJ 繼續讀取AuthAspect的定義,發現了一個around()。 7. AspectJ繼續讀取AuthAspect的定義,發現了一個around()。 這次AspectJ把"Begin Transaction"和"End Transaction"兩段代碼加在Bank.deposit和Bank. withdraw兩個方法的執行前後。這次AspectJ把"Begin Transaction"和"End Transaction"兩段代碼加在Bank.deposit和Bank. withdraw兩個方法的執行前後。 達到的效果就如同Code 2.3所示。達到的效果就如同Code 2.3所示。

如何驗證這一點?如何驗證這一點? 您可以到http://www.eclipse.org/aspectj/下載安裝AspectJ,編譯裡面的Sample,把編譯結果反編譯一下,就可以看到AspetJ自動生成的代碼。您可以到http://www.eclipse.org/aspectj/下載安裝AspectJ,編譯裏面的Sample,把編譯結果反編譯一下,就可以看到AspetJ自動生成的代碼。

我們看到,AspectJ是一種代碼自動生成工具。我們看到,AspectJ是一種代碼自動生成工具。 你編寫一段通用的代碼,比如認證方面的代碼,事務方面的代碼,然後根據AspectJ語法定義一套代碼生成規則(aspect定義),AspectJ就會幫助你自動把這段通用代碼分佈到對應的代碼裡面去,簡單快捷,算無遺策。你編寫一段通用的代碼,比如認證方面的代碼,事務方面的代碼,然後根據AspectJ語法定義一套代碼生成規則(aspect定義),AspectJ就會幫助你自動把這段通用代碼分佈到對應的代碼裏面去,簡單快捷,算無遺策。
我們用AspectJ編譯器編譯Bank文件和含有aspect的這個文件,出來的結果就是帶有安全認證和事務處理的Bank類。我們用AspectJ編譯器編譯Bank文件和含有aspect的這個文件,出來的結果就是帶有安全認證和事務處理的Bank類。 編譯出來的這個Bank 類調用了AspectJ Runtime Lib,所以,如果你要運行這個Bank類,你需要把AspectJ Runtime Lib設置在你的classpath裡面。編譯出來的這個Bank類調用了AspectJ Runtime Lib,所以,如果你要運行這個Bank類,你需要把AspectJ Runtime Lib設置在你的classpath裏面
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章