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 異常解決辦法(14197)
2.?Eclipse下安裝TomcatPlugin插件(8431)
3.?圖形統計工具amCharts體驗(6263)
4.?PL/pgSQL - SQL過程語言(轉)(5581)
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
博客園
模板提供:
滬江博客
主站蜘蛛池模板:
国产精品成人无码免费
|
亚洲真人无码永久在线
|
337P日本欧洲亚洲大胆精品
|
午夜免费福利小电影
|
国产精品高清视亚洲精品
|
免费A级毛片无码A
|
性无码免费一区二区三区在线
|
亚洲大成色www永久网址
|
2048亚洲精品国产
|
日本阿v免费费视频完整版
|
黄网站在线播放视频免费观看
|
国产亚洲人成网站在线观看不卡
|
哒哒哒免费视频观看在线www
|
久久精品私人影院免费看
|
亚洲AV无码精品国产成人
|
国产亚洲福利精品一区
|
日韩电影免费在线
|
最近中文字幕免费大全
|
亚洲国产精品无码久久久秋霞1
|
最新亚洲卡一卡二卡三新区
|
亚洲伊人色欲综合网
|
精品国产精品久久一区免费式
|
中文字幕无码一区二区免费
|
亚洲国产精品无码久久久秋霞1
|
亚洲精品~无码抽插
|
免费国产在线观看
|
真人做人试看60分钟免费视频
|
精品熟女少妇a∨免费久久
|
边摸边吃奶边做爽免费视频99
|
免费大片黄在线观看yw
|
成全视频在线观看免费
|
美女免费精品高清毛片在线视
|
亚洲福利电影一区二区?
|
亚洲一区二区三区影院
|
国产乱弄免费视频
|
成人毛片免费观看视频在线
|
精品国产污污免费网站aⅴ
|
AAA日本高清在线播放免费观看
|
人妻仑刮八A级毛片免费看
|
一个人看的www在线免费视频
|
亚洲一区二区三区播放在线
|