2025-02-10

 by Narayanan A.R. June 15, 2005
翻譯zhangv (derekzhangv.at.hotmail.com)
原文:Java/Article/28422/0/page/3″>http://www.devx.com/Java/Article/28422/0/page/3


圖3

圖3中描述瞭AOP方法的設計以及在一個更抽象的層次上類間的交互.你可以通過對比圖1和圖3來更好地理解AOP.
程序的目的是通過BusinessUnit對象讀取CSV文件中的記錄然後 填入類BusinessUnitService 中的map.使用AOP來填充這個map有點類似後門(backdoor)方法 — 控制被委派給BusinessUnit 來讀取存儲介質中的記錄.

AOP就是定義一些point cut(?)和advice.一個point cut是源代碼中一個執行點.前面的例子定義瞭一個pointcut 給類BusinessUnitService中的findBusinessUnits 方法.一個advice就是當執行到point cut時的一塊代碼.類BusinessUnitPersistentAspect 包括advice方法findAllBusinessUnits,該方法從存儲介質中載入數據,然後使用工廠類創建BusinessUnit 對象.然後這個對象被加入map,map對象的引用通過BusinessUnitService 對象獲得.point cut 和advice組成瞭所謂的”方面(Aspect)”

為瞭讀取存儲介質中的數據,OOP方法通過一個DAO類來做.而AOP中,你在作用域類中定義一個point cut和一個advice來讀取數據.AOP框架會以advice的形式註入代碼,既可以在執行期也可以在編譯期.

總而言之,當類BusinessUnitService 中的findAllBusinessUnits 方法被調用時,AOP框架會註入advice方法並通過BusinessUnit 對象預先讀取數據來填充map對象.這樣,持久層方面的代碼可以從業務模型中移出.

新方法裡的方面

本節討論如何用AOP為應用程序的各方面建模

操作資源

類BusinessUnitPersistenceAspect 的持久方法使用瞭一個buffered reader.你甚至可以定義方面的方面,但為瞭簡單,這裡的討論隻關註類的查找方法.

  1. @Aspect(“perJVM”)
  2. public class BufferedFileReaderAspect {
  3. @Expression(“execution(* org.javatechnocrats.aop.withaop.aspects.BusinessUnitPersistenceAspect.find*(..))”)
  4. Pointcut businessUnitPersistenceAspect;
  5. // 其他point cut 定義
  6. @Expression(“businessUnitPersistenceAspect ||
  7. employeePersistenceAspect ||
  8. managerPersistenceAspect“)
  9. Pointcut allPersistencePointcuts;
  10. private Map<ClassString> fileNames;
  11. public BufferedFileReaderAspect() {
  12. System.out.println(“BufferedFileReaderAspect created”);
  13. fileNames = new HashMap<ClassString>();
  14. fillFileNames();
  15. }
  16. @Before(“allPersistencePointcuts”)
  17. public void assignReader(JoinPoint joinPoint) throws Throwable {
  18. System.out.println(“assignReader advice called”);
  19. Object callee = joinPoint.getCallee();
  20. IBufferedFileReaderConsumable bufReaderConsumable = (IBufferedFileReaderConsumable)callee;
  21. Class persistenceClass = callee.getClass();
  22. String fileName = fileNames.get(persistenceClass);
  23. FileReader fileReader = new FileReader(fileName);
  24. BufferedReader bufferedReader = new BufferedReader(fileReader);
  25. bufReaderConsumable.setBufferedReader(bufferedReader);
  26. }
  27. @AfterFinally(“allPersistencePointcuts”)
  28. public void releaseReader(JoinPoint joinPoint) throws Throwable {
  29. //釋放buffered reader等資源
  30. }
  31. //其他方法
  32. }



上面的代碼試圖為每一個方法名創建一個point cut — 所有以find開頭的方法.無論何時這些方法被調用,assignReader方法都會被提前執行.這裡它獲取被調用的類實例然後設置新建的buffered reader.

同樣地,在releaseReader 方法裡,代碼會預先關閉buffered reader集合.本節隻解釋@before和@
AfterFinally 這兩個point cut.(以J2SE 5.0的標記定義).另外,你也可以在方面定義的xml文件中聲明他們.你可以查看那例程源代碼中的aop.xml文件.

下載

持久化

前面提到,OOP方法使用BusinessUnit 來為應用的持久層填充Map.在下面的高亮代碼中(@before一行,以及while循環代碼 – 譯者註),當BusinessUnitService 中的方法findAllBusinessUnits 被調用時advice方法findAllBusinessUnits 也將被調用.

  1. @Aspect(“perJVM”)
  2. public class BusinessUnitPersistenceAspect implements IBufferedFileReaderConsumable {
  3. private BufferedReader buffFileReader;
  4. @Before(“execution(Collection org.javatechnocrats.aop.withaop.BusinessUnitService.findAllBusinessUnits())”)
  5. public void findAllBusinessUnits(JoinPoint joinPoint) throws Throwable {
  6. System.out.println(“findAllBusinessUnits advice called”);
  7. Map<String, BusinessUnit> busin

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *