欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java Cglib動態(tài)代理

 更新時間:2020年08月18日 11:45:20   作者:弗蘭克的貓  
這篇文章主要介紹了Java Cglib動態(tài)代理的相關(guān)資料,幫助大家更好的理解和學習Java代理,感興趣的朋友可以了解下

  今天來介紹另一種更為強大的代理——Cglib動態(tài)代理。

  什么是Cglib動態(tài)代理?

  我們先回顧一下上一篇的jdk動態(tài)代理,jdk動態(tài)代理是通過接口來在運行時動態(tài)創(chuàng)建委托類的代理對象,但是跟靜態(tài)代理一樣有一個缺點,就是必須和委托類實現(xiàn)相同的接口,當接口數(shù)量增加時,便需要增加代理類的數(shù)量才能滿足需求,而且如果委托類是別人寫的,而且沒有實現(xiàn)任何接口,那么jdk動態(tài)代理就有些力不從心了。

  這時候Cglib動態(tài)代理就脫穎而出了,Cglib并不依賴接口,可以直接生成委托類的代理對象,而且可以代理委托類的任意非final修飾的public和protected方法,我們可以先來看一個栗子。

  先定義一個Programmer類:

public class Programmer {

 private String name;
 
 public void setName(String name) {     System.out.println("Setting Name.");
 this.name = name;
 }public void code(){
 System.out.println(name + " is writing bugs.");
 }
}

  然后定義一個代理類:

public class ProgrammerProxy implements MethodInterceptor {

 /**
 * 內(nèi)部持有委托類對象的引用
 */
 private Object target;

 /**
 * 創(chuàng)建代理類對象
 */
 public Programmer createProxy(Programmer object){
 target = object;
 //創(chuàng)建Enhancer對象
 Enhancer enhancer = new Enhancer();
 //設(shè)置要代理的目標類,以擴展功能
 enhancer.setSuperclass(this.target.getClass());
 //設(shè)置單一回調(diào)對象,在回調(diào)中攔截對目標方法的調(diào)用
 enhancer.setCallback(this);
 //設(shè)置類加載器
 enhancer.setClassLoader(object.getClass().getClassLoader());
 //創(chuàng)建代理對象
 return (Programmer)enhancer.create();
 }

 /**
 * 回調(diào)方法:在代理實例上攔截并處理目標方法的調(diào)用,返回結(jié)果
 * @param proxy 代理類
 * @param method 被代理的方法
 * @param params 該方法的參數(shù)數(shù)組
 * @param methodProxy
 */
 @Override
 public Object intercept(Object proxy, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
 //調(diào)用之前處理
 doBefore();

 //調(diào)用原方法
 method.invoke(target,params);

 //調(diào)用之后處理
 doAfter();

 return null;
 }

 private void doAfter() {
 System.out.println("do after.");
 }

 private void doBefore() {
 System.out.println("do before.");
 }

}

  然后測試一下:

public class ProxyTest {

 @Test
 public void testCglibProxy(){
 //創(chuàng)建一個Programmer對象
 Programmer programmerA = new Programmer();
 programmerA.setName("Frank");

 //創(chuàng)建代理對象
 Programmer programmerProxyA = new ProgrammerProxy().createProxy(programmerA);
 programmerProxyA.code();

 //修改代理對象
 programmerProxyA.setName("Wang");
 programmerProxyA.code();

 //修改委托類對象
 programmerA.setName("Song");
 programmerProxyA.code();
 }
}

  輸出如下:

Setting Name.
do before.
Frank is writing bugs.
do after.
do before.
Setting Name.
do after.
do before.
Wang is writing bugs.
do after.
Setting Name.
do before.
Song is writing bugs.
do after.

  Cglib實現(xiàn)動態(tài)代理的步驟也不是很麻煩,先創(chuàng)建一個類實現(xiàn)MethodInterceptor接口,重寫intercept方法,在intercep中可以截獲委托類的所有非final修飾的public和protected方法,上例中,method.invoke(target,params);即為調(diào)用原對象的原方法,在代理類中保存了委托類對象的引用,這一點跟JDK動態(tài)代理是一樣的。在調(diào)用原方法前先調(diào)用了doBefore方法,調(diào)用之后還調(diào)用了doAfter方法,從而實現(xiàn)了代理功能。至于createProxy方法,也只是一個固定步驟,先創(chuàng)建Enhance對象,然后將委托類的一些屬性往里塞,然后調(diào)用create方法來動態(tài)生成代理對象。

  在測試類中,為了更明顯的說明代理類與委托類的關(guān)系,分別用代理類對象programmerProxyA和委托類對象programmerA對name字段進行修改,可以產(chǎn)生一樣的效果。

  下面來對比一下Cglib動態(tài)代理與JDK動態(tài)代理:

  1.兩者都是動態(tài)代理,都是運行時動態(tài)生成代理對象。

  2.JDK動態(tài)代理利用的是接口信息來實現(xiàn)的代理,委托類必須實現(xiàn)某個或者某些接口,而Cglib則是利用繼承關(guān)系,利用asm在運行時動態(tài)生成委托類的子類,從而實現(xiàn)對委托類的代理。因此不依賴接口。

  3.Cglib由于是利用繼承關(guān)系來實現(xiàn)代理的,因此無法代理被final修飾的類以及被final修飾的方法。

  4.Cglib一般來說效率要比JDK動態(tài)代理效率更高,可以實現(xiàn)的代理也更為強大。

  當然,具體情況具體分析,雖然Cglib比Jdk動態(tài)代理更強大,但并不一定各個地方都強行使用,有時候JDK動態(tài)代理相對來說更加簡單粗暴。

  至此,本篇完結(jié),代理相關(guān)內(nèi)容講解完畢,歡迎大家繼續(xù)關(guān)注。

jar包下載地址:http://www.dbjr.com.cn/softs/570453.html

以上就是詳解Java Cglib動態(tài)代理的詳細內(nèi)容,更多關(guān)于Java Cglib動態(tài)代理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringMVC中的HandlerMapping詳解

    SpringMVC中的HandlerMapping詳解

    這篇文章主要介紹了SpringMVC中的HandlerMapping詳解,HandlerMapping是請求映射處理器,也就是通過請求的url找到對應(yīng)的邏輯處理單元(Controller),注意這里只是建立請求與Controller的映射關(guān)系,最終的處理是通過HandlerAdapt來進行處理的,需要的朋友可以參考下
    2023-09-09
  • Java代碼規(guī)范與質(zhì)量檢測插件SonarLint的使用

    Java代碼規(guī)范與質(zhì)量檢測插件SonarLint的使用

    本文主要介紹了Java代碼規(guī)范與質(zhì)量檢測插件SonarLint的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • Java實現(xiàn)一鍵獲取Mysql所有表字段設(shè)計和建表語句的工具類

    Java實現(xiàn)一鍵獲取Mysql所有表字段設(shè)計和建表語句的工具類

    這篇文章主要為大家詳細介紹了如何利用Java編寫一個工具類,可以實現(xiàn)一鍵獲取Mysql所有表字段設(shè)計和建表語句,感興趣的小伙伴可以了解一下
    2023-05-05
  • MyBatis延遲加載與立即加載案例教程

    MyBatis延遲加載與立即加載案例教程

    這篇文章主要介紹了MyBatis延遲加載與立即加載案例教程,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • SpringBoot 定時任務(wù)遇到的坑

    SpringBoot 定時任務(wù)遇到的坑

    這篇文章主要介紹了SpringBoot 定時任務(wù)遇到的坑,今天踩的這個坑和 cron 表達式有關(guān),文中給大家介紹了cron 表達式的解釋,需要的朋友一起看看吧
    2017-11-11
  • Java異常處理學習心得

    Java異常處理學習心得

    本篇文章給大家詳細講述了學習Java異常處理學習的心得以及原理介紹,對此有興趣的朋友參考下吧。
    2018-01-01
  • Java面向?qū)ο笾畠?nèi)部類詳解

    Java面向?qū)ο笾畠?nèi)部類詳解

    在 Java 中,允許一個類的定義位于另一個類的內(nèi)部,前者稱為內(nèi)部類,后者稱為外部類。這篇文章將總結(jié)一下內(nèi)部類的使用,感興趣的可以了解一下
    2022-10-10
  • Spring中BeanFactory和ApplicationContext的作用和區(qū)別(推薦)

    Spring中BeanFactory和ApplicationContext的作用和區(qū)別(推薦)

    這篇文章主要介紹了Spring中BeanFactory和ApplicationContext的作用和區(qū)別,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法

    EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法

    這篇文章主要介紹了EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • java Arrays快速打印數(shù)組的數(shù)據(jù)元素列表案例

    java Arrays快速打印數(shù)組的數(shù)據(jù)元素列表案例

    這篇文章主要介紹了java Arrays快速打印數(shù)組的數(shù)據(jù)元素列表案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論