《AspectJ Cookbook》讀書筆記二十: 應(yīng)用類和組件級方面
創(chuàng)建一個模塊化參數(shù)檢查邏輯的方面。聲明一個切入點,用于捕獲其中將檢查參數(shù)的方法的執(zhí)行。切入點應(yīng)該把參數(shù)展示給相應(yīng)的通知使得它可以執(zhí)行檢查。
依賴于參數(shù)檢查的結(jié)果,通知將繼續(xù)執(zhí)行方法,或者每當參數(shù)不合適時都重寫方法。
傳統(tǒng)的參數(shù)驗證和檢查代碼:



































通過方面的應(yīng)用,可以改成如下:




























































二. 重寫在構(gòu)造函數(shù)調(diào)用上實例化的類





以上代碼為了改變MyInterface的實現(xiàn),必須把代碼改成:
MyIntrface myObject = new AnotherClass();
通過使用AspectJ的call(Signature)切入點和around()通知,可以使得事情更簡單,更整潔。如:




















進一步,可以檢查用戶定義的運行時參數(shù):
Object aound():myClassConstructor()&&if (System.getProperty("select_class")).equals("AnotherClass") {
return new AnotherClass();
}
三.添加持久性到類中
可以把這個抽象方面擴展成一些特殊化的子方面,他們將會應(yīng)用程序內(nèi)的每個持久對象集合實現(xiàn)一個合適的持久性機制。

























PersistenceAspect抽象方面把ObjfctStore角色定義為接口,可以將其應(yīng)用與任何類,來管理對象集合的持久性。restoreStorage(ObjectStore)和persistStorage(ObjectStore)抽象切入點通過特殊化的子方面來實現(xiàn),用于觸發(fā)對應(yīng)的after()通知塊,它將恢復(fù)或保持指定的ObjectStore.
ObjectStore接口中指定的restore()和persist()方法是依據(jù)特地ingde持久性策略實現(xiàn)的,該策略用于應(yīng)用程序內(nèi)的對象集合,使得可以基于每個ObjectStore來改變持久性策略。































































EmployeePersistenceAspect將ObjectStore接口應(yīng)用于EmployeeCollection類。然后實現(xiàn)restoreStorage(ObjectStore)方面,以捕獲何時構(gòu)造EmployeeCollection,并使用target(TypePattern || Identifier)切入點將EmployeeCollection展示為要存儲的ObjectStore.
實現(xiàn)persistStorage(ObjectStore)切入點,用以捕獲無論何時更改EmployeeCollection,并在此時保持ObjectStore的內(nèi)容。EmployeeCollection是ArrayList的特殊化;為了避免直接織入到Java標準庫中,使用call(Signature)切入點來捕獲何時在List上調(diào)用add(...)方法。
不過,call(Signature)切入點定義本質(zhì)上過于普通,因此必須將通過persistStorage(ObjectStore)切入點捕獲的連接點限制于只捕獲何時在EmployeeCollection上調(diào)用add(...)。為了應(yīng)用這種限制,第一個target(TypePattern || Identifier)切入點使用TypePattern來指定你只對其目標是EmployeeCollection類的連接點感興趣。第二個target(TypePattern || Identifier)切入點使用一個標識符將當前ObjectStore傳遞給通知塊,作為persistStorage(ObjectStore)切入點的單一參數(shù)。
最后,將直觀的對象串行化持久性策略應(yīng)用于EmployeeCollction。EmployeeCollection中的每個對象都是Employee類的一個實例,并且擴展這個類以實現(xiàn)Serializable接口,使得可對它應(yīng)用標準的Java對象串行化技術(shù)。串行化的Employee對象將存儲在一個文件中;因此,將以employeesFile屬性的形式把這個文件信息添加到EmployeeCollection類中。
為了完成圖形,將把persist()和restore()方法實現(xiàn)添加到EmployeeCollection類中,使得它可以滿足ObjectStore接口所需的行為。這些方法會執(zhí)行Employee對象的串行化和恢復(fù),這是通過employeesFile屬性指定的文件來進行的。
以下顯示了抽象的PersistenceAspect替代實現(xiàn)的一部分,它只會在關(guān)閉應(yīng)用程序關(guān)閉時保持其對應(yīng)的ObjectStore.

















































































persistStore(ObjectStore)切入點修改成捕獲Runnable的執(zhí)行,它在MyApplication類上強制執(zhí)行public void run()方法。然后,AccountPersistenceAspect把必要的run()方法實現(xiàn)添加到MainApplication類中,以滿足Runnable接口的需要,但是,這只會提供一個標記,而不需要任何實現(xiàn)。
增加Runnable接口和MainApplication類上的run()存根方法意味著:可以利用JVM把MainApplication注冊為關(guān)閉掛鉤,使得在整個應(yīng)用程序正常完成時將調(diào)用MainApplication.run()方法。在恢復(fù)ObjectStore(它是一個MainApplication類)時,通過執(zhí)行around(MainApplication)通知塊,來完成把MainApplication類注冊為關(guān)閉掛鉤的任務(wù)。
通過把MainApplication用作關(guān)閉掛鉤,當觸發(fā)關(guān)閉掛鉤時,persistStoreage(ObjectStore)切入點將觸發(fā)MainApplication對象的保持操作。因此,一旦干凈利索地關(guān)閉應(yīng)用程序,就會保持MainApplication中存儲的Account類的集合。
四. 應(yīng)用模擬組件支持單元測試
創(chuàng)建組件所依賴的外部組件的模擬實現(xiàn)。創(chuàng)建一個方面,應(yīng)用模擬組件實現(xiàn)來代替真實的組件。單元測試完成時,使用單獨的AspectJ構(gòu)建配置文件裝換出測試文件,使得可以再次使用真實的實現(xiàn)。
以下為一種典型情況,MyComponent是要測試的組件,并且它具有與ThirdPartyComponentInterface的外部實現(xiàn)的依賴性。ThirdPartyComponentInterface的真實實現(xiàn)是通過調(diào)用工廠方法ThirdPartyFactory.getThirdPartyComponent()來獲得的。





















為了孤立地對MyComponent運行單元測試,將需要通過在測試中包括真實的外部組件,重寫ThirdPartyComponent實現(xiàn),從而不會混淆測試結(jié)果。一種策略是:手動應(yīng)用重寫真實組件實現(xiàn)的模擬組件。如:















以上方法如果用在組件較多的接口,可能難以管理。使用面向方面的替代方法,可以創(chuàng)建一個方面,用于截獲ThirdPartyComponent的創(chuàng)建,并用模擬對象實現(xiàn)重寫返回的對象。















可以通過創(chuàng)建兩個不同的AspectJ構(gòu)建配置文件,來區(qū)分真實實現(xiàn)和模擬實現(xiàn)。
posted on 2008-08-29 11:18 Brian 閱讀(341) 評論(0) 編輯 收藏 所屬分類: 《AspectJ Cookbook》讀書筆記