proxy妯″紡綆浠?/span>
GoF浠嬬粛浜唒roxy妯″紡銆備唬鐞嗗璞′負(fù)鍏朵粬瀵硅薄鎻愪緵涓縐嶄唬鐞嗕互鎺у埗瀵硅繖涓璞$殑璁塊棶銆傚畠闈欐佺粨鏋勫涓嬶細(xì)
Client
闇瑕佽闂?/span>
RealSubject
鏃訛紝瀹冨疄闄呰闂殑鏄?/span>
Proxy
瀵硅薄錛岃屽悗
Proxy
瀵硅薄灝嗚姹傚鎵樼粰
RealSubject
銆?/span>
RealSubject
瀹炵幇浜嗕富瑕佺殑閫昏緫錛?/span>
Proxy
瀵硅薄鍙互鍦ㄥ鐞嗚姹備箣鍓嶃佷箣鍚庝綔棰濆鐨勫鐞嗐傚彲浠ョ湅鍑猴紝
Proxy
鍜?/span>
RealSubject
瀹炵幇浜嗗悓鏍風(fēng)殑鎺ュ彛錛岃繖鏍?/span>
Client
鎵嶅彲浠ヨ皟鐢?/span>
RealSubject
瀹炵幇鐨勬墍鏈?/span>
Subject
鐨勬柟娉曘?/span>
鎴戜滑鍦ㄥ疄鐜?/span>
Proxy
鏃訛紝濡傛灉浣跨敤鐨勬槸
C++
璇█錛屾垜浠彲浠ラ噸杞芥搷浣滅
->
鏉ュ疄鐜頒唬鐞嗐備紭鐐規(guī)槸瀹炵幇綆鍗曪紝緙虹偣鏄畠涓嶈兘鍖哄埆瀵瑰緟涓嶅悓鐨勮姹傘傚綋鐒朵篃鍙互鏄敤鏅氱殑褰㈠紡錛屽垱寤轟竴涓唬鐞嗙被錛屽疄鐜版帴鍙o紝騫跺皢璋冪敤濮旀墭緇欒浠g悊鐨勫璞°?/span>
濡傛灉浣跨敤鐨勬槸
Java
璇█錛屾垜浠綋鐒跺彲浠ヤ嬌鐢ㄦ櫘閫氱殑褰㈠紡鏉ュ疄鐜?/span>
Proxy
妯″紡銆備絾鏄?/span>
JDK1.3
寮曞叆浜?/span>
dynamic proxy
錛屽畠鍏佽鎴戜滑鏇村鏄撶殑瀹炵幇浠g悊銆?/span>
浜屻?/span>
JDK涓殑Dynamic Proxy浠嬬粛
瀹冪敱
java.lang.reflect.Proxy
銆?/span>
java.lang.reflect.InvocationHandler
絳夌粍鎴愩?/span>
Proxy
綾繪嫢鏈変竴涓?/span>
protected
鐨?/span>
InvocationHandler
綾誨瀷鐨勬垚鍛樺彉閲忋?/span>
瀹冨彧鑳戒唬鐞?/span>
Interface銆?/span>
瀹冪殑鍩烘湰鎬濇兂濡備笅錛?/span>
1.聽聽聽聽
浠g悊綾葷敱
Proxy
鐨勯潤鎬佹柟娉?/span>
getProxyClass
鏉ュ姩鎬佺殑鍒涘緩鍑烘潵銆傝鏂規(guī)硶鎵闇瑕佺殑涓涓弬鏁頒負(fù)瀹冩墍浠g悊鐨勬帴鍙f暟緇勩傚垱寤哄嚭鏉ョ殑浠g悊綾誨疄鐜頒簡鎵鏈夌殑鎺ュ彛錛屽茍涓旂戶鎵夸簡
Proxy
銆?/span>
2.聽聽聽聽
浠g悊綾誨疄鐜扮殑鎺ュ彛鏂規(guī)硶鐨勫鐞嗛昏緫涓猴紝璋冪敤鐖剁被鐨?/span>
InvocationHandler
綾誨瀷鐨勬垚鍛樺彉閲忕殑
invoke
鏂規(guī)硶銆?/span>
鐢辨鍙互鐪嬪嚭錛屽繀欏昏
Proxy
瀵硅薄鎷ユ湁涓涓紜殑
InvocationHandler
鐨勫疄鐜般?/span>
Proxy
瀵硅薄鐢?/span>
Proxy
鐨勯潤鎬佹垚鍛樺嚱鏁?/span>
newProxyInstance
鏉ュ垱寤猴紝璇ュ嚱鏁扮殑鏈鍚庝竴涓弬鏁頒負(fù)
InvocationHandler
綾誨瀷銆傚姩鎬佺敓鎴愮殑浠g悊綾誨疄鐜扮殑鎵鏈夋帴鍙f柟娉曢兘琚鎵樼粰
InvocationHandler
鎺ュ彛鐨?/span>
invoke
鏂規(guī)硶銆?/span>
涓夈?/span>
渚嬪瓙浠g爜
鍋囧鏈夊涓嬫帴鍙o細(xì)
interface Foo {
聽void f(String s);
聽void g(int i);
聽String h(int i, String s);
}
騫朵笖鏈変竴涓疄鐜?/span>
class Implement implements Foo {
聽聽 鈥?/span>
}
鐜板湪鎴戜滑鎯沖湪
Foo
鎺ュ彛鐨勬瘡涓柟娉曡皟鐢ㄦ椂錛屽姞鍏ユ棩鑷熾備竴涓緢綆鍗曞緢鐩磋鐨勬柟娉曞涓嬶細(xì)
class LogProxy implements Foo {
private Foo delegate ;
聽聽 public LogProxy( Foo foo ) {
聽聽聽聽聽聽聽聽聽 delegate = foo ;
}
public String h(int i, String s) {
聽聽聽聽聽 System.out.println(鈥渃all h begin 鈥? ;
聽聽聽聽聽 String result = delegate.h( i , s ) ;
聽聽聽聽聽 System.out.println(鈥渃all h end 鈥? ;
聽聽聽聽聽 Return result ;
}
鈥?/span>
}
new LogProxy( new Implement()
銆
).h( 10 , 鈥渟tr鈥?;
鍙互鐪嬪嚭榪欐牱鐨勫疄鐜頒唬鐮佸緢澶氾紝鑰屼笖鍑犱箮閮芥槸鐩稿悓鐨勩傚綋鐒跺彲浠ョ紪鍐欑▼搴忔潵鍐欏嚭榪欐牱鐨勪唬鐮侊紝浣嗘槸鎴戜滑濡傛灉浣跨敤
JDK1.3
寮曞叆鐨?/span>
dynamic proxy
錛岄偅涔堟儏鍐靛氨瀹屽叏涓嶅悓浜嗐?/span>
鍥涖?/span>
dynamic proxy瀹炵幇Log鐨勪唬鐮?/span>
1.聽聽聽聽聽聽
緙栧啓
InvocationHandler
鐨勫瓙綾伙紝鏉ユ嫤鎴墍鏈夌殑鏂規(guī)硶璋冪敤銆?/span>
class LogProxy implements InvocationHandler {
聽聽聽聽聽 public LogProxy( Object object ) { obj = object ; }
聽聽聽聽聽 public Object invoke(Object proxy, Method method, Object[] args)
聽聽聽聽聽 throws Throwable {聽聽
String methodName = method.getName() ;
System.out.println("call " + methodName聽+ 鈥?begin 鈥?) ;聽聽聽聽聽聽聽
聽聽聽聽聽聽 聽聽聽 Object result = method.invoke( obj , args )聽;
System.out.println("call " + methodName + 鈥?end鈥?) ;聽聽聽聽聽聽聽
聽聽聽 聽聽聽聽聽聽 Return result ;
聽聽聽聽聽 }
聽聽聽聽聽 public Object obj = null ;
}
2.聽聽聽聽聽聽
浣跨敤
Proxy鐨勯潤鎬佹柟娉曟潵鍒涘緩浠g悊綾匯偮?/span>
LogProxy dp = new LogProxy( new Implment() ) ;
Foo proxy = (Foo) Proxy.newProxyInstance(
聽聽聽聽聽聽聽聽聽聽聽 聽聽聽聽聽聽聽聽// [1] class loader
聽聽聽聽聽 聽聽聽聽聽聽聽聽聽聽聽聽聽 Foo.class.getClassLoader(),
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // [2] interface's Class array
聽聽聽聽聽聽 聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 new Class[]{ Foo.class },
聽聽聽聽聽聽 聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // [3] InvocationHandler
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 dp ) ;
3.聽聽聽聽聽聽
瀹㈡埛鍦ㄤ唬鐞嗙被涓婅皟鐢ㄦ柟娉?/span>
proxy.
h( 10 , 鈥渟tr鈥?;
鍙互鐪嬪嚭錛屽鏋滄帴鍙d腑鏈夊緢澶氭柟娉曪紝閭d箞浣跨敤
dynamic proxy
鏄緢鍚堥傜殑錛屼絾鏄鏋滄帴鍙e彧鏈夊緢灝戠殑鏂規(guī)硶錛屽彲鑳戒嬌鐢ㄦ櫘閫氱殑鏂規(guī)硶鏇寸洿瑙傦紝涔熸洿綆鍗曘?/span>
浜斻?/span>
搴旂敤渚嬪瓙
濡傛灉鎴戜滑璁捐涓涓暟鎹簱榪炴帴姹狅紝鎺ュ彛濡備笅錛?/span>
interface DBConnectionPool {
聽聽聽聽聽聽聽聽聽聽聽 public java.sql.Connection getConnection() ;
聽聽聽聽聽聽聽聽聽聽聽 public void releaseConnection( java.sql.Connection conn ) ;
}
class DBConnectionPoolImpl implements DBConnectionPool {
聽聽聽聽聽聽聽聽聽聽聽 鈥?/span>
}
聽
閭d箞涓涓彲鑳界殑鐢ㄦ埛璋冪敤搴忓垪濡備笅錛?/span>
void getData() {
聽聽聽聽聽聽聽聽聽聽聽 DBConnectionPoolImpl聽cpi = new DBConnectionPoolImpl() ;
聽聽聽聽聽聽聽聽聽聽聽 Connection conn = cpi.getConnection() ;
聽聽聽聽聽聽聽聽聽聽聽 // use conn to retrieve data from db
聽聽聽聽聽聽聽聽聽聽聽 鈥?/span>
聽聽聽聽聽聽聽聽聽聽聽 cpi. releaseConnection( conn ) ;
聽聽聽聽聽聽聽聽聽聽聽
}
钃濊壊鐨勪唬鐮佽〃紺轟簡灝嗚繛鎺ヨ繕緇欒繛鎺ユ睜錛屽洜涓烘墍鏈夌殑榪炴帴閮芥槸鐢辮繛鎺ユ睜鏉ョ鐞嗙殑銆備絾鏄繖鏍風(fēng)殑浠g爜瀵圭敤鎴鋒潵璁插彲鑳戒笉澶範(fàn)鎯紝鑰屼笖榪嬌鐢ㄦ埛榪欐牱緙栧啓浠g爜錛岀敤鎴蜂細(xì)鎰忚瘑鍒?/span>
cpi
瀵硅繛鎺ヤ綔浜嗙壒孌婄殑澶勭悊銆?/span>
聽聽聽聽聽聽聽聽聽聽聽
涓涓洿濂界殑鏂規(guī)硶鏄皟鐢?/span>
Connection
鎺ュ彛鐨?/span>
close
鏂規(guī)硶銆傝繖鏍風(fēng)殑浠g爜濡備笅錛?/span>
void getData() {
聽聽聽聽聽聽聽聽聽聽聽 DBConnectionPoolImpl聽cpi = new DBConnectionPoolImpl() ;
聽聽聽聽聽聽聽聽聽聽聽 Connection conn = cpi.getConnection() ;
聽聽聽聽聽聽聽聽聽聽聽 // use conn to retrieve data from db
聽聽聽聽聽聽聽聽聽聽聽 鈥?/span>
聽聽聽聽聽聽聽聽聽聽聽 conn.close() ;
}
榪欐牱鏇寸鍚堟櫘閫氱敤鎴風(fēng)殑緙栫爜涔?fàn)鎯備絾鏄彲浠ヨ繖涔堢紪鐮佺殑鍓嶆彁鏄細(xì)
1銆?/font>
close
鍑芥暟瑕佸皢榪炴帴瀵硅薄榪樼粰榪炴帴姹狅紝鑰屼笉鏄叧闂墿鐞嗙殑鏁版嵁搴撹繛鎺ャ?/span>
2銆?/font>
鎵鏈?/span>
Connection
鐨勫叾浠栧嚱鏁板繀欏昏兘澶熸甯稿伐浣溿?/span>
涔熷氨鏄闇瑕佺壒孌婂鐞?/span>
close
鍑芥暟錛岃屽鍏朵粬鍑芥暟鐩存帴榪涜杞彂灝卞彲浠ヤ簡銆?/span>
鐢ㄦ渶鐩存帴鐨勬柟娉曞疄鐜板涓嬶細(xì)
class ConnectionProxy implements Connection {
聽聽聽聽聽聽聽聽聽聽聽 private Connection realConn ;
聽聽聽聽聽聽聽聽聽聽聽 private DBConnectionPool dbcp ;
聽聽聽聽聽聽聽聽聽聽聽 public ConnectionProxy( Connection conn聽,聽DBConnectionPool pool ) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 realConn = conn ;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 dbcp = pool ;
}
聽
public void close() throws SQLException {
聽聽聽聽聽聽聽聽聽 dbcp. releaseConnection( realConn ) ;
}
聽
public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽 return realConn.prepareStatement( sql , columnNames ) ;
}
//聽聽聽聽聽聽聽 鎵鏈夌殑鍏朵粬Connection鎺ュ彛涓殑鏂規(guī)硶杞彂
鈥?/font>
}
鍙互鐪嬪嚭榪欐牱鐨勫疄鐜頒唬鐮佸緢澶氾紝鑰屼笖鍑犱箮閮芥槸鐩稿悓鐨勩傚綋鐒跺彲浠ョ紪鍐欑▼搴忔潵鍐欏嚭榪欐牱鐨勪唬鐮侊紝濡傛灉浣跨敤
DynamicProxy
錛岄偅涔堟暣涓疄鐜板氨姣旇緝浼橀泤浜嗐?/span>
聽
Classs ConnectionProxy
InvocationHandler {
聽聽 Connection conn ;
聽聽
DBConnectionPool cp ;
Public ConnectionProxy( Connection conn ,
DBConnectionPool cp
) {
This.conn = conn ;
This.cp = cp ;
}
public Object invoke(Object proxy, Method method, Object[] args)
聽聽聽聽聽 throws Throwable {
聽聽聽聽聽聽聽聽聽聽聽聽 Object result = null ;
聽聽聽聽聽聽聽聽聽聽聽聽 if (
鈥渃lose鈥?equals(
method.getName()聽) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 cp.
releaseConnection( conn ) ;
} else {
聽聽聽聽聽聽 聽聽聽 聽result = method.invoke( obj , args )聽;
}
聽聽聽聽聽聽聽聽聽聽 Return result ;
聽聽聽聽聽 }
}
鏈変釜綾?/span>
ConnectionProxy鍚庯紝鎴戜滑鍙渶瑕佽
DBConnectionPool
鐨勬柟娉?/span>
getConnection
榪斿洖鍔ㄦ佷唬鐞嗗嵆鍙傚疄鐜板涓嬶細(xì)
class DBConnectionPoolImpl implements DBConnectionPool {
聽聽聽聽聽聽聽聽聽聽聽 public Connection getConnection() {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Connection conn聽;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 //
浠庢睜涓彇寰楄繛鎺ユ垨寤虹珛榪炴帴
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return (Connection)Proxy.newInstance(
聽聽聽聽聽 聽聽聽聽聽聽聽聽聽聽聽聽聽 Connection.class.getClassLoader(),
聽聽聽 聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 new Class[]{ Connection.class },
聽聽聽聽聽聽聽聽聽聽聽聽 聽聽聽聽聽聽 new
ConnectionProxy( conn )
聽) ;
聽
}
}
榪欐牱灝卞疄鐜頒簡榪炴帴姹犮?/span>
jdk1.5
鎻愪緵鐨勭敤浜?/span>
rmi
鐨?/span>
dynamic stub
涔熶嬌鐢?/span>
dynamic proxy
鎶鏈傚彧瑕佷綘璁ょ湡鐮旂┒錛屽叾瀹炲緢澶氶棶棰橀兘鍙互浣跨敤
dynamic proxy
鏉ヨВ鍐熾?/span>

]]>