自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java帝國之動(dòng)態(tài)代理

開發(fā) 開發(fā)工具 后端
已經(jīng)快三更天了, Java帝國的國王還在看著IO大臣的奏章發(fā)呆,他有點(diǎn)想不明白, 帝國已經(jīng)給臣民了提供了這么多的東西,他們?yōu)槭裁催€不滿意呢? 集合、IO、反射、網(wǎng)絡(luò)、線程、泛型、JDBC ......在IT界哪一個(gè)不都是響當(dāng)當(dāng)?shù)挠餐ㄘ? 有了這些技術(shù),寫個(gè)Java程序多簡(jiǎn)單啊, 臣民們?yōu)楹芜€整天抗議呢?

1.深夜奏對(duì)

已經(jīng)快三更天了, Java帝國的國王還在看著IO大臣的奏章發(fā)呆,他有點(diǎn)想不明白, 帝國已經(jīng)給臣民了提供了這么多的東西,他們?yōu)槭裁催€不滿意呢? 集合、IO、反射、網(wǎng)絡(luò)、線程、泛型、JDBC ......在IT界哪一個(gè)不都是響當(dāng)當(dāng)?shù)挠餐ㄘ? 有了這些技術(shù),寫個(gè)Java程序多簡(jiǎn)單啊, 臣民們?yōu)楹芜€整天抗議呢?

這還是昨天IO大臣的一個(gè)奏章,其中說到各個(gè)部落要醞釀一場(chǎng)大規(guī)模的抗議游行,抗議Java不支持動(dòng)態(tài)性,不能在運(yùn)行時(shí)修改一個(gè)類,導(dǎo)致不能用聲明的方式來編程。

國王憤憤地想,我的政策太開明了,這些刁民不知好歹,蹬鼻子上臉,以后要堅(jiān)決加強(qiáng)東廠西廠錦衣衛(wèi)鎮(zhèn)撫司等紀(jì)檢法的建設(shè),有意見可以上訪, 不能這么胡鬧,增加社會(huì)不穩(wěn)定因素。帝國正在和Python, PHP等國家開戰(zhàn),處處都要銀子,攘外必先安內(nèi)啊。

想到這里,國王立刻命令呂公公宣IO大臣進(jìn)宮。

IO大臣半夜里被從熱騰騰的的被窩里拽出來,心里老大不情愿, 迷迷糊糊地跟著呂公公進(jìn)了宮。

“陛下半夜三更還在為國事操勞,真乃臣等之罪也 !” IO大臣雖然心里不情愿,但還是畢恭畢敬。

“愛卿,你說說這是怎么一回事? 什么是Java 不支持動(dòng)態(tài)性? ”國王拿出了奏章。

IO大臣心里明白了,原來是介個(gè)啊。

“啟奏陛下,其實(shí)這是刁民們羨慕Python 、Ruby 等語言的動(dòng)態(tài)性,想讓我們Java 也支持,他們最想要的一個(gè)功能就是能在運(yùn)行時(shí)對(duì)類進(jìn)行修改,這樣可以用聲明的方式來編程。”

“你能不能說點(diǎn)朕能聽懂的話?” 國王低沉的聲音里隱藏著馬上就要噴薄而出的怨氣,老子想了一晚上都沒整明白,你還在這里給我文縐縐的!

“是這樣” IO大臣開始調(diào)用腦細(xì)胞遣詞造句,準(zhǔn)備用通俗易懂的語言撲滅陛下的怒火。

“所謂運(yùn)行時(shí)對(duì)類進(jìn)行修改,打個(gè)比方來說,我寫了一個(gè)HelloWorld的類,其中有兩個(gè)方法:sayHello()和sayHelloToPHP(),陛下請(qǐng)看: ”

“這是帝國三歲小孩都能明白的代碼,說重點(diǎn)!”

“然后這個(gè)類運(yùn)行起來了,刁民們希望在運(yùn)行的時(shí)候可以修改這類, 譬如加一個(gè)新方法sayHelloToPython(), 或者對(duì)現(xiàn)在的sayHello()方法里加一點(diǎn)新東西, 甚至把sayHelloToPHP()這個(gè)方法刪除!”

“這些刁民太過分了, 難道他們不能寫個(gè)新的類來做這件事嗎?”

“陛下圣明, 臣也覺得可以新寫一個(gè)類比如HelloWorldNew來做這件事情,重新編譯一下不就行了嗎? 可是他們說的是在運(yùn)行時(shí)修改,是運(yùn)行時(shí),運(yùn)行時(shí),運(yùn)行時(shí),重要的事情說三遍,不是編譯時(shí)。”

“運(yùn)行時(shí)? 一個(gè)類一旦裝入到方法區(qū)還怎么修改 ” 國王還是很了解JVM這一套。 “你知道他們?yōu)槭裁从羞@個(gè)要求嗎?”

“他們說了想用聲明的方式來編程.....” IO大臣意識(shí)到大事不好。

“什么是聲明的方式” 國王窮追不舍

“這個(gè)臣還不太清楚......”

“快去徹查,限你三天回話。”

“遵旨”

2.明察暗訪

IO大臣冷汗都出來了, 他睡意全無,趕緊召集家丁幕僚準(zhǔn)備上山下鄉(xiāng)、明察暗訪,限他們兩天把這個(gè)“以聲明的方式編程”搞清楚。

兩天內(nèi)不斷有快馬回報(bào),各種各樣的信息如雪片般飛來。 IO大臣又花了一天時(shí)間整理,終于明白了這個(gè)“以聲明的方式編程”。

原來這幫刁民犯懶,寫完了代碼以后有這樣的需求:

在某些函數(shù)調(diào)用前后加上日志記錄

給某些函數(shù)加上事務(wù)的支持

給某些函數(shù)加上權(quán)限控制

......

這些需求挺通用的,如果在每個(gè)函數(shù)中都實(shí)現(xiàn)一遍,那重復(fù)代碼就太多了。 更要命的是有時(shí)候代碼是別人寫的,你只有class 文件,怎么修改? 怎么加上這些功能?

所以“刁民”們就想了一個(gè)損招,他們想在XML文件或者什么地方聲明一下, 比如對(duì)于添加日志的需求吧, 聲明的大意如下:

對(duì)于com.coderising這個(gè)package下所有以add開頭的方法,在執(zhí)行之前都要調(diào)用Logger.startLog()方法, 在執(zhí)行之后都要調(diào)用Logger.endLog()方法。

對(duì)于增加事務(wù)支持的需求,聲明的大意如下:

對(duì)于所有以DAO結(jié)尾的類,所有的方法執(zhí)行之前都要調(diào)用TransactionManager.begin(),執(zhí)行之后都要調(diào)用TransactionManager.commit(), 如果拋出異常的話調(diào)用TransactionManager.rollback()。

他們已經(jīng)充分發(fā)揮了自己的那點(diǎn)兒小聰明,號(hào)稱是開發(fā)了一個(gè)叫AOP的東西,能夠讀取這個(gè)XML中的聲明, 并且能夠找到那些需要插入日志的類和方法, 接下來就需要修改這些方法了。 但是Java帝國不允許修改一個(gè)已經(jīng)被加載或者正在運(yùn)行的類, 于是他們就不干了,就要抗議、就要游行,就要暴動(dòng), 真是可惡。

IO大臣決定向國王做一次匯報(bào),看看國王的反應(yīng)。

3.Java 動(dòng)態(tài)代理

國王不愧是國王, IO大臣稍微一解釋, 就明白怎么回事了。

“愛卿,你覺得該怎么辦? ” 皮球又被踢到了IO大臣那里。

“臣覺得不能讓這些刁民突破帝國的底線, 我們的class在運(yùn)行時(shí)是不能被修改的,如果也像Python,Ruby 那樣在運(yùn)行時(shí)可以肆意修改,那就太混亂了!” IO大臣小心翼翼地揣摩圣意。

“言之有理, 愛卿有何辦法? ”

“臣想到了一個(gè)辦法,雖然不能修改現(xiàn)有的類,但是可以在運(yùn)行時(shí)動(dòng)態(tài)的創(chuàng)建新的類啊,比如有個(gè)類HelloWorld:

“這么簡(jiǎn)單的類,怎么還得實(shí)現(xiàn)一個(gè)接口呢? ” 國王問道

“臣想給這些刁民們?cè)黾右稽c(diǎn)點(diǎn)障礙, 你不是想讓我動(dòng)態(tài)地創(chuàng)建新的類嗎?你必須得有接口才行啊” IO大臣又得意又陰險(xiǎn)地笑了。

國王臉上也露出了一絲不易覺察的微笑。

“現(xiàn)在他們的問題是要在sayHello()方法中調(diào)用Logger.startLog(), Logger.endLog()添加上日志, 但是這個(gè)sayHello()方法又不能修改了!”

“所以臣想了想, 可以動(dòng)態(tài)地生成一個(gè)新類,讓這個(gè)類作為HelloWorld的代理去做事情(加上日志功能), 陛下請(qǐng)看,這個(gè)HelloWorld代理也實(shí)現(xiàn)了IHelloWorld接口。 所以在調(diào)用方看來,都是IHelloWorld接口, 并不會(huì)意識(shí)到其實(shí)底層其實(shí)已經(jīng)滄海滄田了。”

“朕能明白你這個(gè)綠色的HelloWorld代理,但是你這個(gè)類怎么可能知道把Logger的方法加到什么地方呢?” 國王一下子看出了關(guān)鍵。

“陛下天資聰慧,臣拜服,‘刁民’們需要寫一個(gè)類來告訴我們具體把Logger的代碼加到什么地方, 這個(gè)類必須實(shí)現(xiàn)帝國定義的InvocationHandler接口,該接口中有個(gè)叫做invoke的方法就是他們寫擴(kuò)展代碼的地方。 比如這個(gè)LoggerHandler: ”

“ 看起來有些讓朕不舒服,不過朕大概明白了, 無非就是在調(diào)用真正的方法之前先調(diào)用Logger.startLog(), 在調(diào)用之后在調(diào)用Logger.end(), 這就是對(duì)方法進(jìn)行攔截了,對(duì)不對(duì)?”

“正是如此! 其實(shí)這個(gè)LoggerHandler 充當(dāng)了一個(gè)中間層, 我們自動(dòng)化生成的類$HelloWorld100會(huì)調(diào)用它,把sayHello這樣的方法調(diào)用傳遞給他 (上圖中的method變量),于是sayHello()方法就被添加上了Logger的startLog()和endLog()方法”


 

“此外,臣想提醒陛下的是,這個(gè)Handler不僅僅能作用于IHelloWorld 這個(gè)接口和 HelloWorld這個(gè)類,陛下請(qǐng)看,那個(gè)target 是個(gè)Object, 這就意味著任何類的實(shí)例都可以, 當(dāng)然我們會(huì)要求這些類必須得實(shí)現(xiàn)接口。 臣民們使用LoggerHandler的時(shí)候是這樣的:”

輸出:

Start Logging

Hello World

End Logging

“如果想對(duì)另外一個(gè)接口ICalculator和類Calcualtor做代理, 也可以復(fù)用這個(gè)LoggerHandler的類:”

“折騰了變天,原來魔法是在Proxy.newProxyInstance(....) 這里,就是動(dòng)態(tài)地生成了一個(gè)類嘛, 這個(gè)類對(duì)臣民們來說是動(dòng)態(tài)生成的, 也是看不到源碼的。”

“圣明無過陛下,我就是在運(yùn)行時(shí),在內(nèi)存中生成了一個(gè)新的類,這個(gè)類在調(diào)用sayHello() 或者add()方法的時(shí)候, 其實(shí)調(diào)用的是LoggerHanlder的invoke 方法, 而那個(gè)invoke就會(huì)攔截真正的方法調(diào)用,添加日志功能了! ”

“愛卿辛苦了,雖然有點(diǎn)繞,但是理解了還是挺簡(jiǎn)單的。 朕明天就頒發(fā)圣旨, 全國推行,對(duì)了你打算叫它什么名字? ”

“既然是在運(yùn)行時(shí)動(dòng)態(tài)的生成類,并且作為一個(gè)真實(shí)對(duì)象的代理來做事情, 那就叫動(dòng)態(tài)代理吧!”

動(dòng)態(tài)代理技術(shù)發(fā)布了,臣民們得到了暫時(shí)的安撫,但是這個(gè)動(dòng)態(tài)代理的缺陷就是必須有接口才能工作,帝國的臣民能忍受得了嗎?

【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過作者微信公眾號(hào)coderising獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2011-04-06 11:41:25

Java動(dòng)態(tài)代理

2017-08-16 15:11:29

JavaJDBCJTA

2018-03-29 15:20:05

JavaJaasJdbc

2017-02-27 14:25:50

Java隊(duì)列Web

2017-02-28 08:57:41

JavaJMS隊(duì)列

2012-08-28 10:59:26

JavaJava動(dòng)態(tài)代理Proxy

2011-03-23 10:40:51

java代理模式

2015-09-22 11:09:47

Java 8動(dòng)態(tài)代理

2023-12-06 08:23:44

代理模式設(shè)計(jì)模式

2017-11-22 14:31:24

華為云

2021-07-06 06:39:22

Java靜態(tài)代理動(dòng)態(tài)代理

2015-09-28 15:59:00

Java動(dòng)態(tài)代理機(jī)制

2011-11-17 14:32:45

Java靜態(tài)代理動(dòng)態(tài)代理

2023-02-24 07:42:30

Java動(dòng)態(tài)代理

2017-05-11 21:30:01

Android動(dòng)態(tài)代理ServiceHook

2017-11-14 14:41:11

Java泛型IO

2015-09-24 08:55:14

Java動(dòng)態(tài)代理擴(kuò)展

2015-09-24 08:54:36

java動(dòng)態(tài)代理

2010-04-21 09:26:54

Java動(dòng)態(tài)代理

2012-02-08 10:12:19

Java反射
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)