前面一個(gè)文章里的代碼很簡(jiǎn)單(只是讓大家了解什么是代理),實(shí)現(xiàn)的是靜態(tài)代理,做為電腦代理商的ComputerProxy,在電腦行業(yè) 為電腦生產(chǎn)商(三星,聯(lián)想)和客戶提供服務(wù),提供各種方便。
郁悶的是,如果我現(xiàn)在增加一個(gè)行業(yè),比如下面要講到的Car汽車(chē)行業(yè),那么,我們只能增加一個(gè)代理了,也就是說(shuō)我們要再寫(xiě)一個(gè)CarProxy代碼,我們現(xiàn)在假設(shè)我們有很多個(gè)行業(yè),那么,無(wú)疑我們的工作量開(kāi)始大了,有沒(méi)有什么辦法讓我們的代理商實(shí)現(xiàn)跨行業(yè)代理呢?
答案是:可以。這就是我們這里講的動(dòng)態(tài)代理產(chǎn)生存在的意義了。
請(qǐng)看代碼:
在原有代碼的基礎(chǔ)上我們做了這些寬展:

/**//*
*汽車(chē)批發(fā)商
*這樣我們的代碼中就有了電腦和汽車(chē)這兩個(gè)批發(fā)商
*/

public interface Car
{
public void buyCar(String name);
}

/**//*
*勞斯萊斯汽車(chē)公司
*/

public class RollsRoyce implements Car
{


public void buyCar(String name)
{
System.out.println(name+" 勞斯萊斯公司產(chǎn)品!");
}

}

/**//*
*所有行業(yè)代理商
*有了它我們的客戶可以通過(guò)他買(mǎi)個(gè)各種產(chǎn)品
*/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Level;
import java.util.logging.Logger;


public class AllthingsProxy implements InvocationHandler
{

private Logger logger=
Logger.getLogger(this.getClass().getName());
private Object allthings;
//實(shí)現(xiàn)對(duì)象綁定

public Object bind(Object allthings)
{
this.allthings = allthings;
//這里傳入newProxyInstance的參數(shù)分別是 目標(biāo)object
//(Lianxiang,Sanxing),interface(Computer),AllthingsProxy
return Proxy.newProxyInstance(allthings.getClass().getClassLoader(),
allthings.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable
{
Object result = null;

try
{
log("method starts
" + method);
result=method.invoke(allthings, args);

logger.log(Level.INFO , "method ends
" + method);

}catch(Exception e)
{
log(e.toString());
}
return result;
}

private void log(String msg)
{
logger.log(Level.INFO,msg);
}

}
在測(cè)試類BuyAllThings中,我們通過(guò)bing方法綁定對(duì)象(所要買(mǎi)的東西),讓代理商了解到,客戶想買(mǎi)什么?
(這里重在了解模式,具體方法的實(shí)現(xiàn)如不了解請(qǐng)自行查詢API文檔)

/**//*
*三個(gè)客戶兩個(gè)買(mǎi)電腦一個(gè)買(mǎi)汽車(chē)
*他們找到同個(gè)代理商
*/

public class BuyAllThing
{


public static void main(String[] args)
{
AllthingsProxy allthingsproxy = new AllthingsProxy();
Computer SanxingProxy=(Computer)allthingsproxy.bind(new Sanxing());
SanxingProxy.buyComputer("我想買(mǎi)一臺(tái)三星電腦");
Computer lianxiangProxy=(Computer)allthingsproxy.bind(new Lianxiang());
lianxiangProxy.buyComputer("我想買(mǎi)一臺(tái)聯(lián)想電腦");
Car rRollsRoyceProxy=(Car)allthingsproxy.bind(new RollsRoyce());
RollsRoyceProxy.buyCar("我想買(mǎi)一輛勞斯萊斯汽車(chē)");

}

}
執(zhí)行結(jié)果:
我想買(mǎi)一臺(tái)三星電腦 三星電腦公司產(chǎn)品!
我想買(mǎi)一臺(tái)聯(lián)想電腦 聯(lián)想電腦公司產(chǎn)品!
我想買(mǎi)一輛勞斯萊斯汽車(chē) 勞斯萊斯公司產(chǎn)品!
2007-8-9 13:08:41 com.lusm.spring.AllthingsProxy log
信息: method starts
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
信息: method ends
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy log
信息: method starts
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
信息: method ends
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy log
信息: method starts
public abstract void com.lusm.spring.Car.buyCar(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
信息: method ends
public abstract void com.lusm.spring.Car.buyCar(java.lang.String)

我們可以任意的增加代理商的業(yè)務(wù),比如,叫他代理電器,食物......,我們看到我們不需要更改原有的代碼。這是動(dòng)態(tài)代理帶來(lái)的好處!
那我們的AllthingsProxy是怎么作到動(dòng)態(tài)代理的呢?
AllthingsProxy寬展了InvocationHandler并實(shí)現(xiàn)了里面的代理方法,返回一個(gè)Object對(duì)象,
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
來(lái)實(shí)現(xiàn)對(duì)汽車(chē),電腦這些批發(fā)商的動(dòng)態(tài)代理(代理商同過(guò)它 代理所有行業(yè))。
AllthingsProxy中的bind實(shí)現(xiàn)了客戶和代理商間的通信(通過(guò)它代理商知道客戶想要買(mǎi)什么)
這和我們 BuyAllThing 測(cè)試類main中
代理對(duì)象=(綁定對(duì)象)allthingsproxy.bind(綁定對(duì)象(客戶想買(mǎi)的東西))
想對(duì)應(yīng)。
呵呵 ,講完了!也許有的朋友看不懂這里在說(shuō)什么? 不必著急,學(xué)習(xí)都需要過(guò)程,等你的學(xué)習(xí)到某個(gè)階段的時(shí)候,回頭想想,也許認(rèn)識(shí)就會(huì)加深許多,本人覺(jué)得Java是比較高級(jí)的語(yǔ)言,自身的發(fā)展也只直遵循著軟件設(shè)計(jì)優(yōu)化(代碼重用)方向發(fā)展,重視設(shè)計(jì)思想,而不是去改變語(yǔ)言的語(yǔ)法或接口api,這是許多語(yǔ)言所缺乏的,如一個(gè)在VC6中編寫(xiě)的代碼,拿到Visual Studio2005,Visual Studio2008去運(yùn)行很容易出現(xiàn)問(wèn)題。
也許你并不清楚我在說(shuō)什么?但是這一切會(huì)在你的Spring學(xué)習(xí)中漸漸清楚起來(lái)!
以后的代碼可能需要必要的IDE才能使用,本人使用的是:
MyEclipse6.0M1+Eclipse3.3
數(shù)據(jù)庫(kù)用的是:
Oralce10g或者M(jìn)ysql6.0
祝你好運(yùn)氣!!!
地震讓大伙知道:居安思危,才是生存之道。
posted on 2007-08-09 13:49
小尋 閱讀(1474)
評(píng)論(5) 編輯 收藏 所屬分類:
j2se/j2ee/j2me