1. 程式人生 > >java實現動態代理時遇到的問題

java實現動態代理時遇到的問題

java中實現動態代理,用InvocationHandlerProxy就可以了。
所謂的動態代理,就是真正執行操作的物件不是原始的物件,就像A拜託B買東西,然後B買好東西后包裝好給A。
例:

void iTest() throws Exception {
        Foo foo = new Foo();
        IFoo obj = (IFoo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{IFoo.class}, new MIncocationHandler(foo));
        obj.say("hello world"
); } class MIncocationHandler implements InvocationHandler { private Object realObj; public MIncocationHandler(Object obj) { this.realObj = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("begin method invoke"
); method.invoke(realObj, args); System.out.println("after method invoke"); return proxy; } } interface IFoo { public void say(String str); } class Foo implements IFoo{ public void say(String str) { System.out.println(str
); } }

這樣我們就能在不破壞原來的程式碼的情況下,在程式碼執行的前後插入日誌等操作,spring的事務就是利用該原理,但是用的cglib實現的動態代理類的生成,這樣就不用定義介面了,如果按照上面寫的程式碼去實現的話是需要首先定義介面的。

備註:
反射只能得到該類本身的資訊,不能得到父類或者實現的介面的資訊。
介面中的變數是public static final的,方法是public的。

生成的動態代理類實現了Proxy初始化中傳入的所有介面。如果是多個介面的話,就要在handler中的invoke方法中自己判斷是呼叫了哪一個類的方法,不能直接傳遞一個指定的物件了。

如果是多個介面的話,各個介面中的方法不能衝突,例如方法名稱一樣但是返回型別不同,這樣的話實現類就不能確定該實現哪一個方法,因此會初始化代理類失敗