靜態代理和動態代理
A. java動態代理是什麼
JAVA的動態代理
代理模式
代理模式是常用的java設計模式,他的特徵是代理類與委託類有同內樣的介面,代理類主要負容責為委託類預處理消息、過濾消息、把消息轉發給委託類,以及事後處理消息等。代理類與委託類之間通常會存在關聯關系,一個代理類的對象與一個委託類的對象關聯,代理類的對象本身並不真正實現服務,而是通過調用委託類的對象的相關方法,來提供特定的服務。
按照代理的創建時期,代理類可以分為兩種。
靜態代理:由程序員創建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。
動態代理:在程序運行時,運用反射機制動態創建而成。
B. jdk動態代理和cgli代理的區別
當一個對象(客戶端)不能或者不想直接引用另一個對象(目標對象),這時可以版應用代理模式在這兩者權之間構建一個橋梁--代理對象。按照代理對象的創建時期不同,可以分為兩種:
靜態代理:程序員事先寫好代理對象類,在程序發布前就已經存在了;
動態代理:應用程序發布後,通過動態創建代理對象。
其中動態代理又可分為:
1.JDK動態代理
此時代理對象和目標對象實現了相同的介面,目標對象作為代理對象的一個屬性,具體介面實現中,可以在調用目標對象相應方法前後加上其他業務處理邏輯。
代理模式在實際使用時需要指定具體的目標對象,如果為每個類都添加一個代理類的話,會導致類很多,同時如果不知道具體類的話,怎樣實現代理模式呢?這就引出動態代理。
JDK動態代理只能針對實現了介面的類生成代理。
2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的所有方法,所以該類或方法不能聲明稱final的。
C. Spring事務管理是動態代理還是靜態代理 CGLB支持動態代理嗎因為我聽老師說CGLB是靜態代理
JDK動態代理是運行時生成代理對象,其特點是有一個原對象實例,有一個代理對內象實例,代理對象內容部持有原對象的引用。
而CGLIB代理是運行時先編譯一個新的類,直接在位元組碼的層級上把代碼添加進原方法中,運行時只有一個動態生成的新類的實例,不存在源對象實例。
Spring同時支持這兩種代理方式,但是因為JDK動態代理只能進行介面的代理,如果你要代理的對象沒有實現介面,那就不能採取JDK動態代理,而會採用CGLIB代理。
一般情況下優先採用JDK動態代理,雖然其效率似乎比不上CGLIB代理,但是其對象用完之後可以正常釋放。但是CGLIB代理每代理一個對象,都會產生一個新類。而類一旦載入JVM,按照大部分JVM的機制,這些新類佔用的內存不會釋放。J2EE程序一般運行時間都很長,內存上會有一些壓力。
D. 什麼是java代理模式,具體相關的動態代理和靜態代理分別是什麼舉例更好啦~
class a
{
void a1(){System.out.print("a");}
}
class b
{
b()
{
a aa =new a();
}
void b1()
{
aa.a1();
}
}
上邊里例子就是一個簡單的代理模式 在b中建立一個a的對內象 然後b的b1方法容里調研a的a1方法
你只要實例化話一個b的對象的話 調用這個對象的b1方法就和調研a對象的a1方法的效果是完全一樣的
動態代理的話就是在
b()
{
a aa =new a();
}
這個構造參數傳進一個參數 根據這個參數來產生不同的對象(這里一般要用到工廠模式)
根據產生對象的不同調研的方法肯定也就不一樣了
E. 靜態代理,JDK動態代理和CGLib動態代理之前的區別
區別:
java動態抄代理是利用反射機制生成一個實現代理介面的匿名類,在調用具體方法前調用InvokeHandler來處理。而cglib動態代理是利用asm開源包,對代理對象類的class文件載入進來,通過修改其位元組碼生成子類來處理。
1、如果目標對象實現了介面,默認情況下會採用JDK的動態代理實現AOP
2、如果目標對象實現了介面,可以強制使用CGLIB實現AOP
3、如果目標對象沒有實現了介面,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換
F. Java中的動態代理相對於靜態代理有何優點
缺Java中的動態代理相對於靜態代理優點:
1、靜態代理類和委託類實現了相同的介面,代理類通過委託類實現了相同的方法。這樣就出現了大量的代碼重復。如果介面增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。增加了代碼維護的復雜度。
2、靜態代理對象只服務於一種類型的對象,如果要服務多類型的對象。勢必要為每一種對象都進行代理,靜態代理在程序規模稍大時就無法勝任了。如上的代碼是只為UserManager類的訪問提供了代理,但是如果還要為其他類如Department類提供代理的話,就需要我們再次添加代理Department的代理類。
G. 靜態代理,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修飾的類進行代理。
H. Java動態代理與靜態代理的定義與區別
JAVA的靜態代理與動態代理比較
1.靜態代理類:
由程序員創建或由特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。動態代理類:在程序運行時,運用反射機制動態創建而成。
由此可見,代理類可以為委託類預處理消息、把消息轉發給委託類和事後處理消息等。
常式1 HelloService.java
package proxy;
import java.util.Date;
public interface HelloService{
public String echo(String msg);
public Date getTime();
}
2.動態代理類
與靜態代理類對照的是動態代理類,動態代理類的位元組碼在程序運行時由Java反射機制動態生成,無需程序員手工編寫它的源代碼。動態代理類不僅簡化了編程工作,而且提高了軟體系統的可擴展性,因為Java 反射機制可以生成任意類型的動態代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 介面提供了生成動態代理類的能力。
Proxy類提供了創建動態代理類及其實例的靜態方法。
(1)getProxyClass()靜態方法負責創建動態代理類,它的完整定義如下:
public static Class<?> getProxyClass(ClassLoader loader, Class<?>[] interfaces) throws IllegalArgumentException
參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面。
(2)newProxyInstance()靜態方法負責創建動態代理類的實例,它的完整定義如下:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) throws
IllegalArgumentException
參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面,參數handler 指定與動態代理類關聯的 InvocationHandler 對象。
以下兩種方式都創建了實現Foo介面的動態代理類的實例:
/**** 方式一 ****/
//創建InvocationHandler對象
InvocationHandler handler = new MyInvocationHandler(...);
//創建動態代理類
Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });
//創建動態代理類的實例
Foo foo = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
/**** 方式二 ****/
//創建InvocationHandler對象
InvocationHandler handler = new MyInvocationHandler(...);
//直接創建動態代理類的實例
Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler);
由Proxy類的靜態方法創建的動態代理類具有以下特點:
動態代理類是public、final和非抽象類型的;
動態代理類繼承了java.lang.reflect.Proxy類;
動態代理類的名字以「$Proxy」開頭;
動態代理類實現getProxyClass()和newProxyInstance()方法中參數interfaces指定的所有介面;
I. Java動態代理和靜態代理的區別
缺Java中的動態代理相對於靜態代理優點:
1、靜態代理類和委託類實現了相同的接回口,代理類通過委答托類實現了相同的方法。這樣就出現了大量的代碼重復。如果介面增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。增加了代碼維護的復雜度。
2、靜態代理對象只服務於一種類型的對象,如果要服務多類型的對象。勢必要為每一種對象都進行代理,靜態代理在程序規模稍大時就無法勝任了。如上的代碼是只為UserManager類的訪問提供了代理,但是如果還要為其他類如Department類提供代理的話,就需要我們再次添加代理Department的代理類。