上一章主要講述的就是代理模式中的主要的角色,這次就可以放心的說一下springAOP的兩種實現代理模式的方式的區別了。
首先,動態代理,主要涉及的包就是java.lang.reflect包下面的兩個類,Proxy和InvocationHandler,其中InvocationHandler是一個接口,可以通過實現該接口來定義橫切的邏輯,並且通過反射的機制調用目標類的代碼,動態的將橫切的邏輯和業務邏輯整合在一起。這是動態代理的優點,但是它也有不足的地方,就是只能為接口創建代理實例,而沒有通過接口定義業務方法的類,這就需要使用到Cglib代理了。
CGLib底層采用的是字節碼的技術,全稱:Code Generation Library。CgLib可以為一個類創建一個子類,在子類中采用方法攔截的技術攔截所有父類方法的調用並順勢織入橫切邏輯。
也就是說:
JDK動態代理是面向接口的。
CGLib動態代理是通過字節碼底層繼承要代理類來實現(如果被代理類被final關鍵字所修飾,那么抱歉會失敗)。
使用方面應該注意一些地方:
如果要被代理的對象是個實現類,那么Spring會使用JDK動態代理來完成操作(Spirng默認采用JDK動態代理實現機制);
如果要被代理的對象不是個實現類那么,Spring會強制使用CGLib來實現動態代理。
最最重要的來了-----性能方面
我們不管是看書還是看文章亦或是我那個上搜索參考答案,可能很多時候,都可以找到如下的回答:
關於兩者之間的性能的話,JDK動態代理所創建的代理對象,在以前的JDK版本中,性能並不是很高,雖然在高版本中JDK動態代理對象的性能得到了很大的提升,但是他也並不是適用於所有的場景。主要體現在如下的兩個指標中:
1、CGLib所創建的動態代理對象在實際運行時候的性能要比JDK動態代理高不少,有研究表明,大概要高10倍;
2、但是CGLib在創建對象的時候所花費的時間卻比JDK動態代理要多很多,有研究表明,大概有8倍的差距;
3、因此,對於singleton的代理對象或者具有實例池的代理,因為無需頻繁的創建代理對象,所以比較適合采用CGLib動態代理,反正,則比較適用JDK動態代理。
