應用Java Dynamic Proxy 實現類方法的攔截(AOP)
Java Dynamic Proxy 可以對類的指定方法實現攔截,但要求此類要實現某個Interface,攔截的方法出自此Interfacle。基于此,我們可以實現簡單的AOP,要完成方法的攔截,只需要一個InvocationHandler,這個InvocationHandler即是攔截邏輯所在,實現了對目標object指定方法的篩選及調用。比如我們現有一對Interface/Implemention:Speakable/Translater。
Speakable接口指明了可以sayEnglish(),sayChinese()。我們目前的translater實現了這兩個方法。現在我們在此基礎上,增加對translater的方法的logging功能。
在以前,我們可以:
1.直接改寫原代碼,增加logging功能。(ugly)
2.增加一個LoggingTranlater實現Speakable,采用delegation(Design Pattern),對方法進行增強。對此類proxy可以參考jive,其中遍布proxy

現在讓我們來看看Java Dynamic Proxy是如何達到這一點的,聲明我給出的代理是示例性的,比較簡陋,主要是給出一個實現方法,加以改進,即可形成一個比較通用的工具。
先來看看我們的Interface/Implemention對:
































現在我們要進行logging功能了,記住,我們只需提供一個InvocationHandler:










































這個LoggingInvocationHandler實現了InvocationHandler接中。方法的代理調用在invoke(……)中,可以如我添加logging()功能一樣,加入其它的任何想要的功能,然后再進行 real target的方法調用。
如果將logging(Method method)中的邏輯抽出來,放到外部文件(XML)中進行配置讀取。再對方法名采用正則表達式。是不是更為通用了呢?
下面是客戶端調用:





























是不是非常簡單呢?:)
如果到此為止,還是看不出Dynamic在哪兒的,想想我這兒給出的示例與spring的AOP的不同,呵呵,區別在于我這兒給出的Main亦是spring AOP的一部分,在spring里, 對某個Interface的target的代理,采用了Reflection,以達到普遍適用的,不用象我這樣直接顯式地給出類名而已。若我把Main做成一個Helper類,同時,把配置接口及他的實現類都放到外部XML中配置,是不是就有點象一個超級簡化的spring AOP了?
當然spring不是完全用Java Dynamic Proxy的,因為Java Dynamic Proxy的前提——針對接口編程!,針對普通的類的AOP,Spring采用了字節碼增強來實現。
posted on 2005-03-04 10:37 carob 閱讀(2598) 評論(0) 編輯 收藏 所屬分類: Reflection