在目前的Java開發包中包含了對動態代理的支援,但是其實現只支援對介面的的實現。其實現主要通過是java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler介面。Proxy類主要用來擷取動態代理對象,InvocationHandler介面用來限制式呼叫者實現,如下,HelloWorld介面定義的業務方法,HelloWorldImpl是HelloWorld介面的實現,HelloWorldHandler是InvocationHandler介面實現。代碼如下:業務介面:
| public interface HelloWorld { void sayHelloWorld() ;} |
業務介面實現:
| public class HelloWorldImpl implements HelloWorld { public void sayHelloWorld() { System.out.println("Hello World!"); }} |
InvocationHandler實現,需要在介面方法調用前後加入一部份處理工作,這裡僅僅在方法調用前後向後台輸出兩句字串,其代碼如下:
| import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method; public class HelloWorldHandler implements InvocationHandler { //要代理的原始對象 private Object objOriginal; /** * 建構函式。 * @param obj 要代理的原始對象。 */ public HelloWorldHandler(Object obj) { this.objOriginal = obj ; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result ; //方法調用之前 doBefore(); //調用原始對象的方法 result = method.invoke(this.objOriginal ,args); //方法調用之後 doAfter(); return result ; } private void doBefore() { System.out.println("before method invoke!"); } private void doAfter() { System.out.println("after method invoke!"); }} |
測試代碼:
| import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { HelloWorld hw = new HelloWorldImpl(); InvocationHandler handler = new HelloWorldHandler(hw); HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance( hw.getClass().getClassLoader(), hw.getClass().getInterfaces(), handler); proxy.sayHelloWorld(); }} |
Ø 首先擷取一個業務介面的實現對象;Ø 擷取一個InvocationHandler實現,此處是HelloWorldHandler對象;Ø 建立動態代理對象;Ø 通過動態代理對象調用sayHelloWorld()方法,此時會在原始對象HelloWorldImpl. sayHelloWorld()方法前後輸出兩句字串。運行測試類別輸出如下:
| before method invoke!Hello World!after method invoke! |
此處Test類中的方法調用代碼比較多,在我們的實際應用中可以通過設定檔來來簡化用戶端的調用實現。另外也可以通過動態代理來實現簡單的AOP。