欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java動(dòng)態(tài)代理的實(shí)現
動(dòng)態(tài)代理作為代理模式的一種擴展形式,廣泛應用于框架(尤其是基于A(yíng)OP的框架)的設計與開(kāi)發(fā),本文將通過(guò)實(shí)例來(lái)講解Java動(dòng)態(tài)代理的實(shí)現過(guò)程。
友情提示:本文略有難度,讀者需具備代理模式相關(guān)基礎知識,
。
通常情況下,代理模式中的每一個(gè)代理類(lèi)在編譯之后都會(huì )生成一個(gè)class文件,代理類(lèi)所實(shí)現的接口和所代理的方法都被固定,這種代理被稱(chēng)之為靜態(tài)代理(Static Proxy)。那么有沒(méi)有一種機制能夠讓系統在運行時(shí)動(dòng)態(tài)創(chuàng )建代理類(lèi)?答案就是本文將要介紹的動(dòng)態(tài)代理(Dynamic Proxy)。動(dòng)態(tài)代理是一種較為高級的代理模式,它在事務(wù)管理、AOP(Aspect-OrientedProgramming,面向方面編程)等領(lǐng)域都發(fā)揮了重要的作用。
在傳統的代理模式中,客戶(hù)端通過(guò)Proxy類(lèi)調用RealSubject類(lèi)的request()方法,同時(shí)還可以在代理類(lèi)中封裝其他方法(如preRequest()和postRequest()等)。如果按照這種方法使用代理模式,那么代理類(lèi)和真實(shí)主題類(lèi)都應該是事先已經(jīng)存在的,代理類(lèi)的接口和所代理方法都已明確指定,如果需要為不同的真實(shí)主題類(lèi)提供代理類(lèi)或者代理一個(gè)真實(shí)主題類(lèi)中的不同方法,都需要增加新的代理類(lèi),這將導致系統中的類(lèi)個(gè)數急劇增加,因此需要想辦法減少系統中類(lèi)的個(gè)數。動(dòng)態(tài)代理可以讓系統能夠根據實(shí)際需要來(lái)動(dòng)態(tài)創(chuàng )建代理類(lèi),讓同一個(gè)代理類(lèi)能夠代理多個(gè)不同的真實(shí)主題類(lèi)而且可以代理不同的方法。
從JDK 1.3開(kāi)始,Java語(yǔ)言提供了對動(dòng)態(tài)代理的支持,Java語(yǔ)言實(shí)現動(dòng)態(tài)代理時(shí)需要用到位于java.lang.reflect包中的一些類(lèi),現簡(jiǎn)要說(shuō)明如下:
(1) Proxy類(lèi)
Proxy類(lèi)提供了用于創(chuàng )建動(dòng)態(tài)代理類(lèi)和實(shí)例對象的方法,它是所創(chuàng )建的動(dòng)態(tài)代理類(lèi)的父類(lèi),它最常用的方法如下:
public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces):該方法用于返回一個(gè)Class類(lèi)型的代理類(lèi),在參數中需要提供類(lèi)加載器并需要指定代理的接口數組(與真實(shí)主題類(lèi)的接口列表一致)。
public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h):該方法用于返回一個(gè)動(dòng)態(tài)創(chuàng )建的代理類(lèi)的實(shí)例,方法中第一個(gè)參數loader表示代理類(lèi)的類(lèi)加載器,第二個(gè)參數interfaces表示代理類(lèi)所實(shí)現的接口列表(與真實(shí)主題類(lèi)的接口列表一致),第三個(gè)參數h表示所指派的調用處理程序類(lèi)。
(2) InvocationHandler接口
InvocationHandler接口是代理處理程序類(lèi)的實(shí)現接口,該接口作為代理實(shí)例的調用處理者的公共父類(lèi),每一個(gè)代理類(lèi)的實(shí)例都可以提供一個(gè)相關(guān)的具體調用處理者(InvocationHandler接口的子類(lèi))。在該接口中聲明了如下方法:
public Object invoke(Objectproxy, Method method, Object[] args):該方法用于處理對代理類(lèi)實(shí)例的方法調用并返回相應的結果,當一個(gè)代理實(shí)例中的業(yè)務(wù)方法被調用時(shí)將自動(dòng)調用該方法。invoke()方法包含三個(gè)參數,其中第一個(gè)參數proxy表示代理類(lèi)的實(shí)例,第二個(gè)參數method表示需要代理的方法,第三個(gè)參數args表示代理方法的參數數組。
動(dòng)態(tài)代理類(lèi)需要在運行時(shí)指定所代理真實(shí)主題類(lèi)的接口,客戶(hù)端在調用動(dòng)態(tài)代理對象的方法時(shí),調用請求會(huì )將請求自動(dòng)轉發(fā)給InvocationHandler對象的invoke()方法,由invoke()方法來(lái)實(shí)現對請求的統一處理。
下面通過(guò)一個(gè)簡(jiǎn)單實(shí)例來(lái)學(xué)習如何使用動(dòng)態(tài)代理模式:
Sunny軟件公司欲為公司OA系統數據訪(fǎng)問(wèn)層DAO增加方法調用日志,記錄每一個(gè)方法被調用的時(shí)間和調用結果,現使用動(dòng)態(tài)代理進(jìn)行設計和實(shí)現。
本實(shí)例完整代碼如下所示:
[java]
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.GregorianCalendar;
//抽象UserDAO:抽象主題角色
interface AbstractUserDAO {
public Boolean findUserById(String userId);
}
//抽象DocumentDAO:抽象主題角色
interface AbstractDocumentDAO {
public Boolean deleteDocumentById(String documentId);
}
//具體UserDAO類(lèi):真實(shí)主題角色
class UserDAO implements AbstractUserDAO {
public Boolean findUserById(String userId) {
if (userId.equalsIgnoreCase("張無(wú)忌")) {
System.out.println("查詢(xún)ID為" + userId + "的用戶(hù)信息成功!");
return true;
}
else {
System.out.println("查詢(xún)ID為" + userId + "的用戶(hù)信息失??!");
return false;
}
}
}
//具體DocumentDAO類(lèi):真實(shí)主題角色
class DocumentDAO implements AbstractDocumentDAO {
public Boolean deleteDocumentById(String documentId) {
if (documentId.equalsIgnoreCase("D001")) {
System.out.println("刪除ID為" + documentId + "的文檔信息成功!");
return true;
}
else {
System.out.println("刪除ID為" + documentId + "的文檔信息失??!");
return false;
}
}
}
//自定義請求處理程序類(lèi)
class DAOLogHandler implements InvocationHandler {
private Calendar calendar;
private Object object;
public DAOLogHandler() {
}
//自定義有參構造函數,用于注入一個(gè)需要提供代理的真實(shí)主題對象
public DAOLogHandler(Object object) {
this.object = object;
}
//實(shí)現invoke()方法,調用在真實(shí)主題類(lèi)中定義的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeInvoke();
Object result = method.invoke(object, args); //轉發(fā)調用
afterInvoke();
return null;
}
//記錄方法調用時(shí)間
public void beforeInvoke(){
calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
String time = hour + ":" + minute + ":" + second;
System.out.println("調用時(shí)間:" + time);
}
public void afterInvoke(){
System.out.println("方法調用結束!" );
}
}
編寫(xiě)如下客戶(hù)端測試代碼:
[java]
class Client {
public static void main(String args[]) {
InvocationHandler handler = null;
AbstractUserDAO userDAO = new UserDAO();
handler = new DAOLogHandler(userDAO);
AbstractUserDAO proxy = null;
//動(dòng)態(tài)創(chuàng )建代理對象,用于代理一個(gè)AbstractUserDAO類(lèi)型的真實(shí)主題對象
proxy = (AbstractUserDAO)Proxy.newProxyInstance(AbstractUserDAO. class.getClassLoader(), new Class[]{AbstractUserDAO.class}, handler);
proxy.findUserById("張無(wú)忌"); //調用代理對象的業(yè)務(wù)方法
System.out.println("------------------------------");
AbstractDocumentDAO docDAO = new DocumentDAO();
handler = new DAOLogHandler(docDAO);
AbstractDocumentDAO proxy_new = null;
//動(dòng)態(tài)創(chuàng )建代理對象,用于代理一個(gè)AbstractDocumentDAO類(lèi)型的真實(shí)主題對象
proxy_new = (AbstractDocumentDAO)Proxy.newProxyInstance(Abstract DocumentDAO.class.getClassLoader(), new Class[]{AbstractDocumentDAO.class}, handler);
proxy_new.deleteDocumentById("D002"); //調用代理對象的業(yè)務(wù)方法
}
}
編譯并運行程序,輸出結果如下:
調用時(shí)間:13:47:14
查詢(xún)ID為張無(wú)忌的用戶(hù)信息成功!
方法調用結束!
------------------------------
調用時(shí)間:13:47:14
刪除ID為D002的文檔信息失??!
方法調用結束!
通過(guò)使用動(dòng)態(tài)代理,我們可以實(shí)現對多個(gè)真實(shí)主題類(lèi)的統一代理和集中控制。
注:JDK中提供的動(dòng)態(tài)代理只能代理一個(gè)或多個(gè)接口,如果需要動(dòng)態(tài)代理具體類(lèi)或抽象類(lèi),可以使用CGLib(Code Generation Library)等工具,CGLib是一個(gè)功能較為強大、性能和質(zhì)量也較好的代碼生成包,在許多AOP框架中都得以廣泛應用,大家可以自行查閱相關(guān)資料來(lái)學(xué)習CGLib。
【作者:劉偉  http://blog.csdn.net/lovelion
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Java網(wǎng)絡(luò )編程精解之Java語(yǔ)言的反射機制二
Java 動(dòng)態(tài)代理機制分析及擴展
一文讀懂Java動(dòng)態(tài)代理
java動(dòng)態(tài)代理實(shí)現與原理詳細分析
Java JDK 動(dòng)態(tài)代理使用及實(shí)現原理分析
Java代理模式實(shí)現與詳解(二)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久