henry1451 的專欄
BlogJava
首頁
新隨筆
新文章
聯系
聚合
管理
posts - 60,comments - 71,trackbacks - 0
<
2008年7月
>
日
一
二
三
四
五
六
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
(6)
給我留言
查看公開留言
查看私人留言
我參與的團隊
架構師之家(0/0)
隨筆檔案
2009年9月 (1)
2009年6月 (1)
2009年5月 (2)
2009年4月 (3)
2009年3月 (2)
2009年1月 (1)
2008年12月 (3)
2008年11月 (2)
2008年10月 (3)
2008年9月 (7)
2008年8月 (9)
2008年7月 (23)
2008年6月 (1)
2008年5月 (2)
文章分類
Hibernate技術(5)
Java技術(15)
Jsp,Js,Ajax,Html技術(8)
Linux技術(2)
Oracle技術(9)
Spring技術
Struts,Webwork,Xwork技術(3)
其他相關(1)
開源技術(7)
文章檔案
2008年6月 (27)
2008年5月 (27)
2008年4月 (3)
博客集錦
hk2000c技術專欄
即興的靈感
和風細雨
小方的Java博客
小飛龍
急死我了
每日一得
資源與技術網站
BlogJava熱點分類
BlogJava隨筆
JavaEye
J道
Matrix
Open-open
SourceForge
搜索
最新評論
1.?re: 關于關閉Connection是否會自動關閉Statement,ResultSet問題
謝了, 很受用!
--碼農C
2.?re: ClientAbortException 異常解決辦法
換瀏覽器后可以了
--換瀏覽器后可以了
3.?re: eclipse 下環境變量設置[未登錄]
請問 MAVEN_REPO在哪定義的?
--a
4.?re: 圖形統計工具amCharts體驗
無語
--EE
5.?re: ClientAbortException 異常解決辦法
。。。。。。。
--q
閱讀排行榜
1.?ClientAbortException 異常解決辦法(14215)
2.?Eclipse下安裝TomcatPlugin插件(8432)
3.?圖形統計工具amCharts體驗(6264)
4.?PL/pgSQL - SQL過程語言(轉)(5591)
5.?如何修改存儲過程(4488)
評論排行榜
1.?取得單選按鈕中顯示的內容(9)
2.?ClientAbortException 異常解決辦法(7)
3.?圖形統計工具amCharts體驗(4)
4.?10.1快樂!(4)
5.?重復提交、重復刷新、防止后退的問題以及處理方式(轉)(4)
靜態Proxy與動態Proxy用法淺析(轉)
今天讀了讀夏昕寫的《Spring開發指南》,在“AOP in Spring”一節,作者講述了Spring中如何通過動態AOP來提供內置的AOP支持。“從技術角度來講,所謂動態AOP,即通過動態Proxy模式,在目標對象的方法調用前后插入相應的處理代碼”
作者舉了一些例子來解釋何為靜態Proxy,何為動態Proxy。奈何我根基尚淺,最作者舉的動態Proxy的例子懵懂不解,于是自己嘗試著摸索一番,終于對動態Proxy的用法有了一個初步的認識。
首先還是來看靜態Proxy,就我目前的認識看來,Proxy的主要用途是對類中方法的執行進行一下包裝,在方法執行之前,或之后,或both,加入一些“額外”的操作。典型的應用就是加入事務處理。
靜態Proxy相對來講比較簡單,它是對上面所述思想的一個最直接的實現。
假設我們現在有如下一個接口:
package
aop;
public
interface
Foo
{
public
String getMessage(String arg);
}
以及該接口的一個實現類:
package
aop;
public
class
FooImpl
implements
Foo
{
public
String getMessage(String arg)
{
return
"
hi
"
+
arg;
}
}
那么很容易,我們可以通過如下方式進行調用:
package
aop;
public
class
Test
{
/** */
/**
*
@param
args
*/
public
static
void
main(String[] args)
{
Foo foo
=
new
FooImpl();
String message
=
foo.getMessage(
"
Wing
"
);
System.out.println(message);
}
}
輸出結果:
hi Wing
現在問題來了:如果現在我們想在getMessage()之外添加一些額外的操作,比如在這之前輸出“Begin”,在之后輸出“done”,但又不能改變原有接口,怎么辦?也很簡單,用靜態Proxy就可以很方便的實現:
package
aop;
public
class
StaticProxy implements Foo
{
private
Foo foo;
public
StaticProxy(Foo foo)
{
this
.foo
=
foo;
}
public
void
getMessage(String arg)
{
System.out.println(
"
Begin!
"
);
String message
=
foo.getMessage(arg);
System.out.println(message);
System.out.println(
"
Done!
"
);
}
}
調用:
package
aop;
public
class
TestStaticProxy
{
/** */
/**
*
@param
args
*/
public
static
void
main(String[] args)
{
Foo foo
=
new
StaticProxy(
new
FooImpl());
foo.getMessage(
"
Wing
"
);
}
}
結果:
Begin
!
hi Wing
Done
!
你可以看到,StaticProxy只是在Foo的某實現類基礎上包了一層,當然我們這里加的兩個輸出語句無足輕重,但如果我們把這兩個輸出語句替換成事務處理,意義就大不一樣了。
可見,通過靜態Proxy可以實現我們的需求,但如果我們有十幾、二十個這樣的接口實現類,需要類似的處理,我們怎么辦?難道每個實現類都對應一個Proxy嗎?
這時,我們就需要動態Proxy:
package
aop;
import
java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method;
import
java.lang.reflect.Proxy;
public
class
AOPHandler
implements
InvocationHandler
{
private
Object orginal;
public
Object bind(Object obj)
{
orginal
=
obj;
return
Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
this
);
}
public
Object invoke(Object proxy, Method method, Object[] args)
throws
Throwable
{
System.out.println(
"
Begin!
"
);
Object result
=
method.invoke(orginal, args);
System.out.println(result);
System.out.println(
"
Done!
"
);
return
result;
}
}
第一次看到上面的代碼肯定不知所以,稍后解釋,我們先看如何調用:
package
aop;
public
class
TestAOP
{
/** */
/**
*
@param
args
*/
public
static
void
main(String[] args)
{
AOPHandler handler
=
new
AOPHandler();
Object proxy
=
handler.bind(
new
FooImpl());
String message
=
((Foo) proxy).getMessage(
"
Wing
"
);
System.out.println(message);
}
}
結果:
Begin
!
hi Wing
Done
!
hi Wing
下面來解釋一下AOPHandler這個類:
首先,bind()方法是用來創建動態Proxy實例。動態Proxy也是Proxy,和靜態Proxy一樣,功能上都是為了在調用某接口實現類的方法之余,添加一些額外的操作(比如事務處理),他們(動態和靜態Proxy)都是一種特殊的接口實現類。因此,我們在調用的時候可以用
String message = ((Foo) proxy).getMessage("Wing");
把proxy實例直接cast為Foo類型,并調用foo接口上的方法。
不同的是,靜態Proxy,正如前面看到的,是直接實現了接口,并在接口的方法中直接調用該接口某實現類對應的方法。而動態Proxy,是利用Java.lang.reflect.Proxy類提供的這樣一種機制:當構建Proxy時,我們需要提供接口,以及一個關聯的調用處理程序對象(通常實現了InvocationHandler接口),當我們在Proxy上調用接口上的方法(任意方法)時,將觸發調用InvocationHandler接口定義的invoke()方法,由invoke方法完成相應的操作。
上面的AOPHandler類,是將動態Proxy的構建與InvocationHandler接口的實現結合在了一起。
通過AOPHandler,我們可以在運行時期動態的決定用哪個接口實現類來創建Proxy,而不需事先為每個實現類定義對應的Proxy,靈活性和復用性大大增強。
進一步的,我們可以利用java反射機制,通過類名來得到接口實現類的實例,進而得到該實例的動態Proxy。這樣我們就可以在配置文件里動態指定需要用到的接口實現類,就像Spring中所做的一樣。
posted on 2008-07-10 16:07
henry1451
閱讀(323)
評論(0)
編輯
收藏
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
Copyright ©2025 henry1451 Powered By
博客園
模板提供:
滬江博客
主站蜘蛛池模板:
国产99视频精品免费观看7
|
97国产免费全部免费观看
|
亚洲熟妇av一区
|
国产亚洲综合一区柠檬导航
|
色吊丝最新永久免费观看网站
|
性无码免费一区二区三区在线
|
污污的视频在线免费观看
|
在线观着免费观看国产黄
|
欧洲美女大片免费播放器视频
|
中文字幕亚洲男人的天堂网络
|
亚洲精品无码专区久久久
|
亚洲视频一区在线播放
|
国产精品亚洲一区二区三区在线
|
gogo免费在线观看
|
成在线人直播免费视频
|
久久精品国产亚洲AV未满十八
|
亚洲第一第二第三第四第五第六
|
亚洲人xxx日本人18
|
亚洲av无码专区国产不乱码
|
亚洲一区二区三区高清不卡
|
亚洲v高清理论电影
|
亚洲色av性色在线观无码
|
亚洲激情黄色小说
|
亚洲成av人在线观看网站
|
一级毛片免费一级直接观看
|
成年女人A毛片免费视频
|
免费A级毛片av无码
|
在线观看视频免费国语
|
亚洲一区二区高清
|
在线观看亚洲人成网站
|
在线亚洲v日韩v
|
4444www免费看
|
亚洲国产成人久久综合区
|
久久国产亚洲观看
|
亚洲精品乱码久久久久蜜桃
|
黄色网页在线免费观看
|
好吊妞在线成人免费
|
亚洲伊人久久大香线蕉综合图片
|
亚洲一区二区三区写真
|
国产一区二区免费视频
|
亚洲AV蜜桃永久无码精品
|