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 異常解決辦法(14199)
2.?Eclipse下安裝TomcatPlugin插件(8431)
3.?圖形統計工具amCharts體驗(6263)
4.?PL/pgSQL - SQL過程語言(轉)(5582)
5.?如何修改存儲過程(4484)
評論排行榜
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
閱讀(320)
評論(0)
編輯
收藏
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
Copyright ©2025 henry1451 Powered By
博客園
模板提供:
滬江博客
主站蜘蛛池模板:
无码精品人妻一区二区三区免费
|
色偷偷噜噜噜亚洲男人
|
国产AV日韩A∨亚洲AV电影
|
成人网站免费大全日韩国产
|
色播精品免费小视频
|
亚洲av成人一区二区三区在线观看
|
亚洲欧洲日韩不卡
|
久久久久亚洲精品无码网址色欲
|
国产青草亚洲香蕉精品久久
|
日本免费在线中文字幕
|
日本免费一区二区三区最新vr
|
亚洲精品色午夜无码专区日韩
|
亚洲综合精品成人
|
精品一卡2卡三卡4卡免费视频
|
免费看www视频
|
久久久久亚洲Av无码专
|
高清免费久久午夜精品
|
免费人成在线视频
|
久久精品国产亚洲av四虎
|
亚洲AV无码AV日韩AV网站
|
91精品啪在线观看国产线免费
|
亚洲精品国产V片在线观看
|
亚洲AV一二三区成人影片
|
日韩免费高清播放器
|
国产性生交xxxxx免费
|
亚洲免费在线视频观看
|
天黑黑影院在线观看视频高清免费
|
免费的一级黄色片
|
亚洲精品国产啊女成拍色拍
|
国产无限免费观看黄网站
|
手机看片久久国产免费
|
亚洲不卡1卡2卡三卡2021麻豆
|
国产成人AV免费观看
|
亚洲 综合 国产 欧洲 丝袜
|
亚洲香蕉在线观看
|
99热这里有免费国产精品
|
国产AV无码专区亚洲AV手机麻豆
|
亚洲av成人一区二区三区观看在线
|
亚洲精品视频观看
|
四虎影视无码永久免费
|
亚洲а∨天堂久久精品
|