999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

動(dòng)態(tài)代理研究與實(shí)現(xiàn)

2009-04-29 00:00:00劉慶杰,孫旭光,白靈
電腦知識(shí)與技術(shù) 2009年36期

摘要:動(dòng)態(tài)代理的基本思想就是建立一個(gè)可以返回動(dòng)態(tài)代理對(duì)象的代理工廠,該代理工廠提供一個(gè)靜態(tài)方法,用戶自己的業(yè)務(wù)處理對(duì)象和系統(tǒng)服務(wù)對(duì)象傳遞給該代理工廠,在代理工廠的內(nèi)部,通過(guò)反射技術(shù),獲得該業(yè)務(wù)邏輯對(duì)象的類對(duì)象,從而自動(dòng)的拼裝一個(gè)業(yè)務(wù)邏輯類的子類,在該子類中,代理工廠自己完成我們業(yè)務(wù)邏輯和系統(tǒng)服務(wù)的動(dòng)態(tài)拼裝,然后代理工廠動(dòng)態(tài)編譯該類,動(dòng)態(tài)生成該代理類的對(duì)象,返回代理對(duì)象給客戶,從而實(shí)現(xiàn)了真正意義上的業(yè)務(wù)邏輯和系統(tǒng)服務(wù)邏輯之間的動(dòng)態(tài)組裝。

關(guān)鍵詞:動(dòng)態(tài)代理;反射;業(yè)務(wù)邏輯;系統(tǒng)服務(wù);業(yè)務(wù)接口;系統(tǒng)服務(wù)接口;動(dòng)態(tài)編譯

中圖分類號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2009)36-10427-03

Danymic Proxy Research and Implements

LIU Qing-jie, SUN Xu-guang, BAI Ling

(Science And Technology Department, Institute Of Disaster Prevention, Sanhe 065201, China)

Abstract: A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. Thus, a dynamic proxy class can be used to create a type-safe proxy object for a list of interfaces without requiring pre-generation of the proxy class, such as with compile-time tools. Method invocations on an instance of a dynamic proxy class are dispatched to a single method in the instance's invocation handler, and they are encoded with a java.lang reflect.Method object identifying the method that was invoked and an array of type Object containing the arguments.

Key words: dynamic proxy; reflect; business logic; business interface; system service Interface; dynamic compilation

我們知道,對(duì)于企業(yè)應(yīng)用開(kāi)發(fā)來(lái)說(shuō),技術(shù)的核心就是通過(guò)DAO實(shí)現(xiàn)業(yè)務(wù)對(duì)象的增、刪、查、改,我們將這部分功能稱之為業(yè)務(wù)邏輯。但是,基于各種各樣的原因,我們?cè)谡鎸?shí)的業(yè)務(wù)邏輯代碼執(zhí)行之前,總是需要首先執(zhí)行一些系統(tǒng)級(jí)服務(wù):例如執(zhí)行時(shí)間測(cè)試、記錄日志、安全檢查、權(quán)限審核、事務(wù)等業(yè)務(wù)。傳統(tǒng)的做法是,直接將實(shí)現(xiàn)系統(tǒng)服務(wù)的代碼放置在我們的業(yè)務(wù)邏輯代碼之前。這樣開(kāi)發(fā)帶來(lái)的問(wèn)題就是:一方面我們所有的業(yè)務(wù)邏輯代碼之前都放置大量的重復(fù)的系統(tǒng)服務(wù)代碼,造成一種虛假的代碼膨脹。另一方面我們的系統(tǒng)服務(wù)代碼和我們的業(yè)務(wù)邏輯代碼緊密耦合,非常的不利于應(yīng)用的擴(kuò)展、遷移和升級(jí)。解決之道就是——代理模式。

1 代理模式的解耦原理

代理模式分為靜態(tài)代理和動(dòng)態(tài)代理。[1]靜態(tài)代理的實(shí)現(xiàn)原理就是在使用簡(jiǎn)單的繼承方法,用一個(gè)新的類繼承我們的 DAOImpl類,然后再子類中將系統(tǒng)服務(wù)代碼加入,然后調(diào)用父類的業(yè)務(wù)邏輯代碼。這樣就把我們的系統(tǒng)服務(wù)代碼放置在子類,業(yè)務(wù)邏輯代碼放置在父類,實(shí)現(xiàn)簡(jiǎn)單解耦。一旦需要有變化,直接丟棄子類,然后再父類上的業(yè)務(wù)邏輯類上進(jìn)行二次開(kāi)發(fā),并沒(méi)有帶來(lái)多少擴(kuò)展和升級(jí)上的方便。還有一種辦法就是動(dòng)態(tài)代理,也叫動(dòng)態(tài)植入,就是動(dòng)態(tài)生成業(yè)務(wù)邏輯類的子類,在子類中自動(dòng)將我們開(kāi)發(fā)好的系統(tǒng)服務(wù)代碼植入到業(yè)務(wù)邏輯代碼之前。對(duì)于我們用戶來(lái)說(shuō),我們只要將我們的業(yè)務(wù)邏輯處理對(duì)象和系統(tǒng)服務(wù)對(duì)象傳遞給代理工廠,代理工廠自動(dòng)幫助我們生成一個(gè)代理對(duì)象,我們通過(guò)代理對(duì)象調(diào)用我們的業(yè)務(wù)邏輯。因?yàn)榇韺?duì)象是動(dòng)態(tài)生成,就實(shí)現(xiàn)了真正意義上的,我們的業(yè)務(wù)邏輯代碼和系統(tǒng)服務(wù)代碼的分離,各自的擴(kuò)展和升級(jí)不會(huì)對(duì)對(duì)方產(chǎn)生任何影響,實(shí)現(xiàn)真正意義上的解耦。

2 動(dòng)態(tài)代理的實(shí)現(xiàn)思想

要實(shí)現(xiàn)動(dòng)態(tài)代理,首先必須有一個(gè)統(tǒng)一的接口,讓我們的業(yè)務(wù)邏輯實(shí)現(xiàn)類該接口,這樣我們動(dòng)態(tài)生成的代理類和我們的業(yè)務(wù)邏輯類就有了統(tǒng)一訪問(wèn)接口;其次,為我們的系統(tǒng)服務(wù)類開(kāi)發(fā)一個(gè)統(tǒng)一的接口,然后我們所有的系統(tǒng)服務(wù)類必須實(shí)現(xiàn)該接口。最后,開(kāi)發(fā)我們代理工廠類,該代理工廠類代理,對(duì)外提供一個(gè)用來(lái)生成動(dòng)態(tài)代理對(duì)象的靜態(tài)方法,在該方法內(nèi)部,通過(guò)接收的業(yè)務(wù)對(duì)象和系統(tǒng)服務(wù)對(duì)象,動(dòng)態(tài)的構(gòu)建一個(gè)代理類源碼,然后動(dòng)態(tài)編譯該類,最后動(dòng)態(tài)生成一個(gè)代理對(duì)象,返回給客戶。

通過(guò)分析,我們知道,[2]實(shí)現(xiàn)一個(gè)動(dòng)態(tài)代理的關(guān)鍵是如果創(chuàng)建一個(gè)能夠自動(dòng)生成動(dòng)態(tài)代理對(duì)象的代理工廠。開(kāi)發(fā)動(dòng)態(tài)代理工廠的第一關(guān)鍵是如果能夠生成動(dòng)態(tài)代理類的源代碼。本文使用反射技術(shù)獲得動(dòng)態(tài)業(yè)務(wù)接口和系統(tǒng)服務(wù)接口的內(nèi)部方法,自己手動(dòng)的拼裝出該動(dòng)態(tài)代理類的源代碼;開(kāi)發(fā)代理工廠第二個(gè)關(guān)鍵是如果能夠在運(yùn)行期自動(dòng)將我們的動(dòng)態(tài)代理類源碼編譯成字節(jié)碼。JDK6.0提供了一個(gè)Compiler API,能夠是實(shí)現(xiàn)自動(dòng)編譯,本人采用這個(gè)辦法。

3 實(shí)現(xiàn)動(dòng)態(tài)代理工廠類

1) 首先編寫一個(gè)對(duì)外提供服務(wù)的靜態(tài)方法,該方法接收兩個(gè)參數(shù),一個(gè)是業(yè)務(wù)邏輯接口,一個(gè)是系統(tǒng)服務(wù)接口。

public static Object newDynanProxy(Class intf, SystemService service){}

2) 通過(guò)業(yè)務(wù)邏輯類對(duì)象,反射內(nèi)部方法,拼裝動(dòng)態(tài)代理類的內(nèi)部代碼

String str1= \"\";

String line = \"\\r\\";

//獲得業(yè)務(wù)邏輯類的所有方法對(duì)象

Method[] methods = intf.getMethods();

/*每次循環(huán),拼裝出一個(gè)動(dòng)態(tài)代理類的方法方法的內(nèi)部,調(diào)用我們的系統(tǒng)服務(wù)對(duì)象的接口方法,同時(shí)

將我們的業(yè)務(wù)邏輯方法對(duì)象傳遞到系統(tǒng)服務(wù)接口方法中*/

for(int i=0;i

str1 += \"@Override\" + line+

\"public void \" + methods[i].getName() + \"() {\" + line+

\"try {\" + line+

\"Method md = \" + intf.getName() + \".class.getMethod(\\\"\" + methods[i].getName() + \"\\\");\" + line+

\"service.invoke(this, md);\" + line+

\"}catch(Exception ex) {}\" + line+

\"}\";

3) 繼續(xù)拼裝動(dòng)態(tài)代理類源代碼,將我們的動(dòng)態(tài)代理類的方法封裝到一個(gè)動(dòng)態(tài)代理類中

Stringcode =

\"package com.fzxy.proxy;\" +line+

\"importjava.lang.reflect.Method;\" + line+

\"public class $Proxy1 implements \" + intf.getName() + \"{\" + line+

\"public $Proxy1(SystemService service) {\" + line+

\"this.service = service;\" + line+

\"}\" + line+

\"com.fzxy.proxy.SystemServiceservice;\" + line+

str1+

\"}\";

4) 創(chuàng)建一個(gè)臨時(shí)文件,將該動(dòng)態(tài)代理類源代碼輸入到該臨時(shí)文件

String file = System.getPropeline y(\"user.dir\")+\"/com/bjsxt/proxy/$Proxy1.java\";

File f = new File(fileName);

FileWriter fw = new FileWriter(f);

fw.write(code);

fw.flush();

fw.close();

5) 使用JDK6.0 Comiler動(dòng)態(tài)編譯該源代碼文件

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

StandardJavaFileManager fileMgr = compiler.getStandardFileManager(1, 1, 1);

Iterable units = fileMgr.getJavaFileObjects(fileName);

CompilationTask t = compiler.getTask(1, fileMgr, 1, 1, 1, units);

t.call();

fileMgr.close();

6) 動(dòng)態(tài)裝載該動(dòng)態(tài)代理類,創(chuàng)建一個(gè)代理對(duì)象對(duì)象,返回該對(duì)象

URL[] urls = new URL[] {new URL(\"file:/\" + fileName)};

URLClassLoader ul = new URLClassLoader(urls);

Class c = ul.loadClass(\"com.fzxy.proxy.$Proxy1\");

Constructor ctr = c.getConstructor(SystemService.class);

Object m = ctr.newInstance(service);

return m;

4 系統(tǒng)服務(wù)接口的實(shí)現(xiàn)

所有類型的系統(tǒng)服務(wù)類必須實(shí)現(xiàn)該接口,這樣,我們的代理工廠就可以通過(guò)約定的接口方法,在生成的動(dòng)態(tài)代理類方法中調(diào)用該接口方法,將調(diào)用真是的調(diào)用傳遞到該系統(tǒng)服務(wù)對(duì)象的接口方法中。

package com.fzxy.proxy;

public interface SystemService{

public void invoke(Object o, Method m);

}

5 應(yīng)用舉例

我們實(shí)現(xiàn)一個(gè)訂單處理類,該類提供訂單的增刪改查業(yè)務(wù);現(xiàn)在我們希望能夠測(cè)試訂單增刪改查的執(zhí)行時(shí)間,因?yàn)樵摴ぷ鞑粚儆谟唵翁幚順I(yè)務(wù)必須的工作,所以我們不希望執(zhí)行時(shí)間測(cè)試的代碼和我們的訂單業(yè)務(wù)處理緊耦合。[3]按照動(dòng)態(tài)代理的思想,我們可以講執(zhí)行時(shí)間測(cè)試封裝為一個(gè)系統(tǒng)服務(wù)類,通過(guò)我們的動(dòng)態(tài)代理工廠,為我們生成一個(gè)能夠測(cè)試訂單業(yè)務(wù)執(zhí)行時(shí)間的動(dòng)態(tài)代理對(duì)象,通過(guò)該對(duì)象,我們就可以獲得一個(gè)能夠測(cè)試執(zhí)行時(shí)間的訂單處理對(duì)象的時(shí)間代理對(duì)象。

1) 開(kāi)發(fā)一個(gè)時(shí)間測(cè)試系統(tǒng)服務(wù)類,該類實(shí)現(xiàn)系統(tǒng)服務(wù)接口

package com.fzxy.proxy;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

public class TimeSystemService implements SystemService

{private Object target;

public TimeHandler(Object target)

{this.target = target;

}@Override

public void invoke(Object o, Method m)

{long start = System.currentTimeMillis();

try {m.invoke(target);

} catch (Exception e)

{e.printStackTrace();

}

long end = System.currentTimeMillis();

System.out.println(\"執(zhí)行時(shí)間:\" + (end-start)+\"毫秒\");

}}

2) 開(kāi)發(fā)一個(gè)訂單業(yè)務(wù)處理接口

package com.fzxy.service;

public interface OrderManager

{void addOrder(Order order);

void findOrder(int id);

void updateOrder(Order order);

void deleteOrder(int id);}

3) 開(kāi)一個(gè)訂單業(yè)務(wù)處理類

package com.fzxy.service;

public interface OrderManagerImpl

{public void findOrder(int id)

{//查找的業(yè)務(wù)代碼

}

public void addOrder(Order order)

{//增加的業(yè)務(wù)代碼

}

public void updateOrder(Order order)

{//更新的業(yè)務(wù)代碼

}

public void deleteOrder(int id)

{//刪除的邏輯代碼

}}

4) 使用動(dòng)態(tài)代理工廠實(shí)現(xiàn)訂單業(yè)務(wù)邏輯和執(zhí)行時(shí)間測(cè)試的系統(tǒng)服務(wù)邏輯的動(dòng)態(tài)拼裝。

OrderManager mgr = new OrderManagerImpl();

SystemServiceservice = new TimeSystemService(mgr);

OrderManagermgrproxy= (OrderManager)Proxy.newProxyInstance(UserMgr.class,h);

//下面代碼是通過(guò)代理對(duì)象實(shí)現(xiàn)

mgrproxy.addOrder(new Order());

mgrproxy.updateOrder(new Order());

mgrproxy.deleteOrder(1);

mgrproxy.findOrder(2);

6 結(jié)束語(yǔ)

動(dòng)態(tài)代理在各種中間件中大量應(yīng)用,例如:Spring的AOP、連接池、RMI、等。動(dòng)態(tài)代理能夠?qū)崿F(xiàn)真正意義上的不相關(guān)業(yè)務(wù)的動(dòng)態(tài)組裝,對(duì)于不同業(yè)務(wù)的人員,只需要專注自己業(yè)務(wù)的開(kāi)發(fā),不需要知道其它業(yè)邏輯的存在。動(dòng)態(tài)代理一面可以很好的實(shí)現(xiàn)軟件不同業(yè)務(wù)邏輯的解耦,還可以減少軟件開(kāi)發(fā)人員掌握不同業(yè)務(wù)邏輯代理的邏輯爆炸的壓力,對(duì)于提交軟件質(zhì)量,輕松實(shí)現(xiàn)軟件的擴(kuò)展和升級(jí)都有非常重要的現(xiàn)實(shí)意義。

參考文獻(xiàn):

[1] 閻宏.Java與設(shè)計(jì)模式[M].北京:郵電出版社,2008.

[2] 透明.代理模式的前世今生[M].北京:清華大學(xué)出版社,2008.

[3] Hou F.Dynamic Proxy 在Java RMI中的應(yīng)用[M].北京:清華大學(xué)出版社,2009.

主站蜘蛛池模板: 欧美精品亚洲日韩a| 欧美成人午夜视频| 精品久久久久久中文字幕女| 亚洲AⅤ无码日韩AV无码网站| 午夜人性色福利无码视频在线观看| 亚洲第一在线播放| 欧美午夜一区| 久久夜色精品国产嚕嚕亚洲av| 这里只有精品在线| 亚洲AⅤ综合在线欧美一区| 国产性生大片免费观看性欧美| 亚洲综合色区在线播放2019| 成人精品视频一区二区在线 | 色久综合在线| 激情综合激情| 国产第四页| 岛国精品一区免费视频在线观看| 女人18一级毛片免费观看| 国产在线高清一级毛片| 亚洲一区毛片| 在线不卡免费视频| 99re在线免费视频| 草草影院国产第一页| 久草热视频在线| 999精品视频在线| 免费日韩在线视频| 色吊丝av中文字幕| 蜜芽国产尤物av尤物在线看| 国产免费观看av大片的网站| 日本成人在线不卡视频| 不卡网亚洲无码| 亚洲人成在线免费观看| 国产成人无码播放| 孕妇高潮太爽了在线观看免费| 久久精品亚洲中文字幕乱码| 午夜精品久久久久久久无码软件| 99精品视频在线观看免费播放| 一级片一区| 亚洲一区二区三区麻豆| 国产精品久久自在自线观看| 国产成年女人特黄特色毛片免| 青青青伊人色综合久久| 国产精品久久久久无码网站| 在线播放精品一区二区啪视频| 国产午夜无码专区喷水| 国产成人永久免费视频| 久久99这里精品8国产| 国产精品久久国产精麻豆99网站| 无码一区18禁| 男女猛烈无遮挡午夜视频| 日韩AV无码免费一二三区| 国产高清无码第一十页在线观看| 99视频精品全国免费品| 国产精品丝袜视频| 无码网站免费观看| 精品福利视频网| 美女扒开下面流白浆在线试听| 中文字幕在线欧美| 久久久久久久久久国产精品| 亚洲日本在线免费观看| 18黑白丝水手服自慰喷水网站| 国产成人亚洲欧美激情| 99热国产这里只有精品9九| 又污又黄又无遮挡网站| 精品视频一区在线观看| 伊伊人成亚洲综合人网7777| 午夜福利视频一区| 婷婷六月在线| 中美日韩在线网免费毛片视频| 成人福利一区二区视频在线| 欧美日韩v| 麻豆精品久久久久久久99蜜桃| 九九视频免费在线观看| 亚洲无码高清视频在线观看| www.91在线播放| 国产a网站| 久久亚洲高清国产| 无码福利视频| 亚洲成a人在线播放www| 综合人妻久久一区二区精品 | 四虎亚洲国产成人久久精品| 天堂成人在线视频|