有許多方法可以生成動態代理類,例如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
}
}