walterwing
日歷
<
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
統計
隨筆 - 12
文章 - 1
評論 - 7
引用 - 0
導航
BlogJava
首頁
發新隨筆
發新文章
聯系
聚合
管理
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
(1)
給我留言
查看公開留言
查看私人留言
隨筆分類
Java基礎(9)
(rss)
大千世界(2)
(rss)
隨筆檔案
2009年2月 (2)
2008年11月 (2)
2008年10月 (2)
2008年7月 (7)
搜索
最新評論
1.?re: java線程基本知識小結
very good
--very good
2.?re: (轉載)高科技公司的搖籃 — 斯坦福大學[未登錄]
@與你同飛
面包會有的:) 雖然有生之年可能看不到國內大學也能躋身世界前列,但我們也要對自己有信心,哪怕路途再遙遠,也要努力向前
--Wing
3.?re: (轉載)高科技公司的搖籃 — 斯坦福大學
差距啊,差距,什么是差距?這就是差距!
--與你同飛
4.?re: 一道小而精巧的筆試題——Set、equals、類型轉換……
評論內容較長,點擊標題查看
--This is Wing
5.?re: 一道小而精巧的筆試題——Set、equals、類型轉換……
請講講
removeEntryForKey
這段代碼吧,
我是新手,看不懂。
--sclsch
閱讀排行榜
1.?對象的序列化和反序列化(轉載+原創)(4893)
2.?java線程基本知識小結(3358)
3.?(轉載)高科技公司的搖籃 — 斯坦福大學(653)
4.?一道小而精巧的筆試題——Set、equals、類型轉換……(645)
5.?The Collections Framework (摘要)- Part 4(564)
評論排行榜
1.?一道小而精巧的筆試題——Set、equals、類型轉換……(3)
2.?(轉載)高科技公司的搖籃 — 斯坦福大學(2)
3.?java線程基本知識小結(1)
4.?靜態Proxy與動態Proxy用法淺析(0)
5.?The Collections Framework (摘要)- Part 4(0)
靜態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-09 15:08
This is Wing
閱讀(419)
評論(0)
編輯
收藏
所屬分類:
Java基礎
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關文章:
垃圾回收(轉載)
一道小而精巧的筆試題——Set、equals、類型轉換……
對象的序列化和反序列化(轉載+原創)
java線程基本知識小結
靜態Proxy與動態Proxy用法淺析
The Collections Framework (摘要)- Part 4
The Collections Framework (摘要)- Part 3
The Collections Framework (摘要)- Part 2
The Collections Framework (摘要)- Part 1
Copyright © This is Wing
Powered by:
博客園
模板提供:
滬江博客
主站蜘蛛池模板:
久久久WWW成人免费精品
|
黄页网站在线视频免费
|
人妻丰满熟妇无码区免费
|
插鸡网站在线播放免费观看
|
亚洲高清偷拍一区二区三区
|
免费国产黄网站在线看
|
亚洲综合激情另类专区
|
在线观看人成视频免费无遮挡
|
亚洲av永久无码制服河南实里
|
亚洲国产欧美国产综合一区
|
永久免费不卡在线观看黄网站
|
在线观看人成网站深夜免费
|
亚洲日本VA午夜在线影院
|
久久国产免费一区二区三区
|
精品福利一区二区三区免费视频
|
在线永久免费观看黄网站
|
久久亚洲AV成人无码国产电影
|
色欲国产麻豆一精品一AV一免费
|
成年女人男人免费视频播放
|
亚洲AV日韩AV无码污污网站
|
亚洲黄片毛片在线观看
|
中文字幕在线免费看线人
|
亚洲高清美女一区二区三区
|
毛片视频免费观看
|
国产福利电影一区二区三区,免费久久久久久久精
|
毛片免费观看网站
|
性生大片视频免费观看一级
|
亚洲国产成人91精品
|
国产成人免费a在线视频app
|
久久久久久国产a免费观看不卡
|
亚洲美女视频一区二区三区
|
日本免费高清一本视频
|
中文字幕免费在线看线人动作大片
|
日本久久久久亚洲中字幕
|
韩国18福利视频免费观看
|
爽爽爽爽爽爽爽成人免费观看
|
亚洲精品无码久久久久久久
|
免费人成年激情视频在线观看
|
久久午夜无码免费
|
亚洲1区2区3区精华液
|
亚洲AV乱码一区二区三区林ゆな
|