當前位置:成語大全網 - 書法字典 - Java中幾種動態代理的實現及其性能比較

Java中幾種動態代理的實現及其性能比較

1.動態代理是指在運行時動態生成代理類。代理類的字節碼將在運行時生成並加載到當前的類加載器中。

有許多方法可以生成動態代理類,例如JDK自己的動態代理、CGLIB、Javassist或ASM庫。

JDK動態代理使用簡單,並且內置於JDK中,因此無需引入第三方Jar包,但其功能相對較弱。CGLIB和Javassist都是高級字節碼生成庫,它們比JDK提供的動態代理具有更好的整體性能,而且功能非常強大。ASM是壹個低級字節碼生成工具。ASM的使用幾乎是基於用Javabytecode編程,對開發人員的要求較高,也是性能最好的動態代理生日工具。然而,ASM的使用過於繁瑣,其性能並沒有得到數量級的提高。與CGLIB等高級字節碼生成工具相比,ASM程序的可維護性也很差。

JDK實施

1步

1)通過實現InvocationHandler接口創建自己的調用處理程序。

2)通過為代理類指定類加載器對象和壹組接口來創建動態代理類。

3)動態代理類的構造函數通過反射機制獲得,其唯壹的參數類型是調用處理器接口類型。

4)通過構造函數創建壹個動態代理類實例,調用處理器對象在構造時作為參數傳入。

2.創建代理

//InvocationHandlerImpl實現InvocationHandler接口,可以實現代理類到委托類的方法調用的調度和轉發。

//它通常包含對委托類實例的引用,該實例用於實際執行調度轉發的方法調用。

invocation handler handler = new InvocaitonHandlerImpl(..);

//通過代理為包括接口接口的壹組接口動態創建代理類對象。

Class clazz = proxy . getproxyclass(Class loader,new Class【】{ interface . Class,...});

//通過反射從生成的類對象中獲取構造函數對象。

constructor constructor = clazz . get constructor(new Class【】{ invocation handler . Class });

//通過構造函數對象創建動態代理類實例。

Interface Proxy =(Interface)constructor . new instance(new Object【】{ handler });

//proxy類的靜態方法newProxyInstance封裝了上述具體步驟的後三步,簡化了動態代理對象的獲取過程。

//InvocaitonHandlerImpl實現了InvocationHandler接口,可以實現代理類到委托類的方法調用的調度和轉發。

InvocaitonHandler handler = new invocationhandler impl(..);

//直接通過代理創建動態代理類實例。

Interface proxy =(Interface)proxy . new proxy instance(Class loader,new Class【】{ Interface . Class },handler);

3.密碼

/**

*界面

*

*/

公共接口IDBQuery {

字符串請求();

}

/**

*真正的實現類,特定的目標對象

*

*/

公共類DBQuery實現IDBQuery {

公共數據庫查詢(){

嘗試{

thread . sleep(1000);//它可能包括耗時的操作,如數據庫連接。

} catch(中斷異常e ){

e . printstacktrace();

}

}

@覆蓋

公共字符串請求(){

返回“請求字符串”;

}

}

/**

* JDK動態代理實現類

*

*/

公共類JdkDbQueryHandler實現InvocationHandler{

IDBQuery real = null//主題界面

/**

*生成處理程序

*/

@覆蓋

公共對象調用(對象代理、方法方法、對象【】參數)

可投擲的

if(real = = null)

real = new DBQuery();//如果是第壹次調用,則生成壹個真實對象。

返回real . request();//使用真實主題完成實際操作。

}

/**

*使用處理程序生成動態代理對象。

*/

公共靜態IDBQuery createJdkProxy(){

//根據指定的類加載器和接口以及偵聽器返回代理類的實例對象。

//classloader:指定代理對象的類加載器。

//Class【】Interfaces:指定代理對象所有事項的接口。

//InvocationHandler h:指定要調用的InvocationHandler對象。

IDB query JDK proxy =(IDB query)proxy . newproxyinstance(Class loader . getsystemclassloader(),new Class【】{ IDB query . Class },new JdkDbQueryHandler());

返回jdkProxy

}

}