當前位置:首頁 » 代理許可 » jdk動態代理

jdk動態代理

發布時間: 2020-12-08 19:04:20

1. jdk 動態代理與spring 動態代理區別

spring有兩種動態代理方式,一種就是jdk動態代理,還有就是cglib動態代理,jdk動態代理只能代理介面,cglib可以是類。jdk代理生成速度比cglib快,性能沒有cglib好

2. JDK動態代理和CGLIB代理的區別

區別:
java動態代理是利用反射機制生成一個實現代理介面的匿名類,在調用具體方法回前調用InvokeHandler來處理。而cglib動態答代理是利用asm開源包,對代理對象類的class文件載入進來,通過修改其位元組碼生成子類來處理。
1、如果目標對象實現了介面,默認情況下會採用JDK的動態代理實現AOP
2、如果目標對象實現了介面,可以強制使用CGLIB實現AOP
3、如果目標對象沒有實現了介面,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換

3. cglib動態代理和jdk動態代理的區別與應用

jdk動態代理:需要有頂層介面才能使用,但是在只有頂層介面的時候也可以使用,常版見是權mybatis的mapper文件是代理.
cglib動態代理:可以直接代理類,使用位元組碼技術,不能對 final類進行繼承。使用了動態生成位元組碼技術。

4. jdk動態代理與cglib動態代理有什麼區別

  • 1.JDK動態代理

此時代理對象和目標對象實現了相同的介面,目標對象作為代理對象的一個屬性,具體介面實現中,可以在調用目標對象相應方法前後加上其他業務處理邏輯。

代理模式在實際使用時需要指定具體的目標對象,如果為每個類都添加一個代理類的話,會導致類很多,同時如果不知道具體類的話,怎樣實現代理模式呢?這就引出動態代理。

JDK動態代理只能針對實現了介面的類生成代理。

  • 2.CGLIB代理

CGLIB(CODE GENERLIZE LIBRARY)代理是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的所有方法,所以該類或方法不能聲明稱final的。

如果目標對象沒有實現介面,則默認會採用CGLIB代理;

如果目標對象實現了介面,可以強制使用CGLIB實現代理(添加CGLIB庫,並在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。


AOP包括切面(aspect)、通知(advice)、連接點(joinpoint),實現方式就是通過對目標對象的代理在連接點前後加入通知,完成統一的切面操作。

5. 靜態代理,JDK動態代理和CGLib動態代理之前的區別

1、靜態代理:靜態代理中的代理類,需要我們自己寫
JDK動態代理類實現了InvocationHandler介面。在重寫的invoke方法中可以看出,動態代理的基礎是反射(method.invoke(對象,參數)),還好反射看的比較多,到現在還記得。在這里需要提到的是Proxy.newProxyInstance(),這個方法。字面上的意思是 新建一個代理類的實例,這一點就和靜態代理不同了。裡面的參數有三個 類載入器、所有的介面,得到InvocationHandler介面的子類實例。這就是JDK動態代理,該代理有以下幾種特點:
1、Interface:對於JDK Proxy,業務類是需要一個Interface的,這是一個缺陷;
2、Proxy:Proxy類是動態產生的,這個類在調用Proxy.newProxyInstance()方法之後,產生一個Proxy類的實力。實際上,這個Proxy類也是存在的,不僅僅是類的實例,這個Proxy類可以保存在硬碟上;
3、Method:對於業務委託類的每個方法,現在Proxy類裡面都不用靜態顯示出來
4、InvocationHandler:這個類在業務委託類執行時,會先調用invoke方法。invoke方法在執行想要的代理操作,可以實現對業務方法的再包裝。
以上就是JDK動態代理
3、CGLib動態代理:上面的JDK Proxy只能代理實現了介面的類,而不能實現介面的類就不能實現JDK代理。這時候就需要CGLib動態代理類
這里需要注意的是實現MethodIntercetor介面,必須導入cglib-nodep-2.1_3.jar這個包。CGLib是針對類來實現代理的,他的原理是對指定的目標生成一個子類,並覆蓋其中方法實現增強,但因為採用的是繼承,所以不能對final修飾的類進行代理。

6. CGLIB 和 JDK生成動態代理類的區別

CGLIB 和 JDK生成動態代理類區別

  • jdk動態代理的應用前提,必須是目標類基於統一的介面。如果沒有上述前提,jdk動態代理不能應用。

  • cglib這種第三方類庫實現的動態代理應用更加廣泛,並不需要目標類基於統一的介面,且在效率上更有優勢。

下面分別用2個具體例子來詳細闡述

jdk生成代理類

  1. 為目標類(target)定義統一的介面類Service,這個是jdk動態代理必須的前提



    publicinterfaceService{
    /**
    *add方法
    */
    publicvoidadd();

    /**
    *update方法
    */
    publicvoipdate();
    }


2.目標類AService

{
/*
*(non-Javadoc)
*
*@seejdkproxy.Service#add()
*/
publicvoidadd(){
System.out.println("AServiceadd>>>>>>>>>>>>>>>>>>");
}

/*
*(non-Javadoc)
*
*@seejdkproxy.Service#update()
*/
publicvoipdate(){
System.out.println("AServiceupdate>>>>>>>>>>>>>>>");
}
}

3.實現動態代理類MyInvocationHandler,實現InvocationHandler介面,並且實現介面中的invoke方法。在
invoke方法中加入一些代理功能。目標類方法的執行是由mehod.invoke(target,args)這條語句完成。

{
privateObjecttarget;

MyInvocationHandler(){
super();
}

MyInvocationHandler(Objecttarget){
super();
this.target=target;
}

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
throwsThrowable{
//程序執行前加入邏輯,MethodBeforeAdviceInterceptor
System.out.println("before-----------------------------");
//程序執行
Objectresult=method.invoke(target,args);
//程序執行後加入邏輯,MethodAfterAdviceInterceptor
System.out.println("after------------------------------");
returnresult;
}
}

4.測試類,其中增強的目標對象是由Proxy.newProxyInstance(aService.getClass().getClassLoader(), aService.getClass().getInterfaces(), handler);來生成的。

publicclassTest{
publicstaticvoidmain(String[]args){
ServiceaService=newAService();
MyInvocationHandlerhandler=newMyInvocationHandler(aService);
//Proxy為InvocationHandler實現類動態創建一個符合某一介面的代理實例
ServiceaServiceProxy=(Service)Proxy.newProxyInstance(aService
.getClass().getClassLoader(),aService.getClass()
.getInterfaces(),handler);
//由動態生成的代理對象來aServiceProxy代理執行程序,其中aServiceProxy符合Service介面
aServiceProxy.add();
System.out.println();
aServiceProxy.update();
}

cglib動態代理實現AOP攔截

  1. 被代理目標類,cglib不需要目標類實現介面



    publicclassBase{
    /**
    *一個模擬的add方法
    */
    publicvoidadd(){
    System.out.println("add------------");
    }
    }
  2. 實現動態代理類CglibProxy,需要實現MethodInterceptor介面,實現intercept方法。

    {

    publicObjectintercept(Objectobject,Methodmethod,Object[]args,
    MethodProxyproxy)throwsThrowable{
    //添加切面邏輯(advise),此處是在目標類代碼執行之前,即為MethodBeforeAdviceInterceptor。
    System.out.println("before-------------");
    //執行目標類add方法
    proxy.invokeSuper(object,args);
    //添加切面邏輯(advise),此處是在目標類代碼執行之後,即為MethodAfterAdviceInterceptor。
    System.out.println("after--------------");
    returnnull;
    }

    }
  3. 獲取增強的目標類的工廠Factory,其中增強的方法類對象是有Enhancer來實現的

    publicclassFactory{
    /**
    *獲得增強之後的目標類,即添加了切入邏輯advice之後的目標類
    *
    *@paramproxy
    *@return
    */
    publicstaticBasegetInstance(CglibProxyproxy){
    Enhancerenhancer=newEnhancer();
    enhancer.setSuperclass(Base.class);
    //回調方法的參數為代理類對象CglibProxy,最後增強目標類調用的是代理類對象CglibProxy中的intercept方法
    enhancer.setCallback(proxy);
    //此刻,base不是單純的目標類,而是增強過的目標類
    Basebase=(Base)enhancer.create();
    returnbase;
    }
    }
  4. 測試類

    publicclassTest{
    publicstaticvoidmain(String[]args){
    CglibProxyproxy=newCglibProxy();
    //base為生成的增強過的目標類
    Basebase=Factory.getInstance(proxy);
    base.add();
    }
    }



    從上面2個例子,可看出cglib中目標類Base並沒有實現介面,而jdk生成代理類例子中AService 實現了Service介面,所以CGLIB 和 JDK生成動態代理類的區別最大的區別就是目標類是否需要實現介面。

7. JDK動態代理 代理對象跟目標對象不同類型

public class Dog implements Animal{ //這里不知道你的介面是什麼名字,就叫Animal吧
//do something

}
我猜你寫的應該是:
Dog dog = ........;//你在這里用介面的實現類直接實例化,導致報錯
在這里你不能直接實例化Dog對象,應該這樣:
Animal animal = (Dog) ..........;
原因:不能用介面的實現類(Dog)來轉換Proxy的實現類,它們是同級,應該用共同的介面來轉換

8. 如何獲得jdk動態代理proxy的原始類

可以在通知中(如@Before等)通過JoinPoint獲取class對象(proxy):point.getTarget().getClass();
如果proxy實現介面版,再通過class.getInterfaces()即可獲取原始類;
如果proxy是使用繼承權父類的方式,通過class.getSuperClass()即可獲取原始類。

9. JDK的動態代理為什麼必須要使用介面與使用C

代理模式的定義:為其他對象提供一種代理以控制對這個對象的訪問。在內某些情況下,一個對象不適合或容者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。
介面是一種規范,定義了一組相似的行為。
通俗一些就是,當調用代理類的方法時與調用被代理類的方法時在寫法上是沒有任何區別的,只有介面才能保證這種一致性。

10. JDK動態代理生成的代理類在哪兒

spring代理類有用jdk的動態代理,也有用cglib包,cglib底層依賴asm包,asm同樣在hibernate中也被使用,使用asm增強位元組碼,自動生成代理類,方法跟目標類基本一樣

熱點內容
美發店認證 發布:2021-03-16 21:43:38 瀏覽:443
物業糾紛原因 發布:2021-03-16 21:42:46 瀏覽:474
全國著名不孕不育醫院 發布:2021-03-16 21:42:24 瀏覽:679
知名明星確診 發布:2021-03-16 21:42:04 瀏覽:14
ipad大專有用嗎 發布:2021-03-16 21:40:58 瀏覽:670
公務員協議班值得嗎 發布:2021-03-16 21:40:00 瀏覽:21
知名書店品牌 發布:2021-03-16 21:39:09 瀏覽:949
q雷授權碼在哪裡買 發布:2021-03-16 21:38:44 瀏覽:852
圖書天貓轉讓 發布:2021-03-16 21:38:26 瀏覽:707
寶寶水杯品牌 發布:2021-03-16 21:35:56 瀏覽:837