先來看一下jdk動態代理原型:
IUserDao target = new UserDao(); // 給目標對象,創建代理對象 IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance(); // 執行方法 【代理對象】 proxy.save();
第一個結論:其本質與cglib同,都是生成一個子類來模擬“代理”
但是:
動態代理實際上是程序在運行中,根據被代理的接口來動態生成代理類的class文件,並加載class文件運行的過程,通過反編譯被生成的$Proxy0.class文件發現: class類定義為: public final class $Proxy0 extends Proxy implements Interface { public $Proxy0(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); }
由於這個子類要繼承Proxy類獲得有關方法,而java是單繼承的,那么就不能再繼承被代理類了,這是第二個結論:jdk動態代理為什么要接口
那么為什么要繼承Proxy類呢?
因為Proxy內部維護一個InvocationHandler對象進行invoke aop操作,這是第三個結論
而cglib使用asm更直接,直接修改字節碼進行增強子類,故被代理類不能是final的,這是第四個結論
那么為什么不能由Proxy生成代理類的字節碼,在代理類中定義一個變量並傳入InvocationHandler對象的引用,而非繼承Proxy呢?目前是調用父類的構造函數並使用子類傳給父類的InvocationHandler來調用invoke,這個問題待續