詳解Proxy代理模式的場景分析

代理模式是一個十分優秀的軟件架構模式,許多應用都用到了代理模式。代理模式就是爲其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不合適或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。

這次主要講解一下代理模式的實例、解決的問題部分。

在java框架中有一種框架就用到了動態代理模式,spring框架中的aop技術,基於代理模式。下面我將以beforeAdvice來進行這個模式的介紹。

image

這張圖反映了參與到AOP過程中的幾個關鍵組件(以@Before Advice爲例):

  1. 調用者Beans - 即調用發起者,它只知道目標方法所在Bean,並不清楚代理以及Advice的存在
  2. 目標方法所在Bean - 被調用的目標方法
  3. 生成的代理 - 由Spring AOP爲目標方法所在Bean生成的一個代理對象
  4. Advice - 切面的執行邏輯

它們之間的調用先後次序反映在上圖的序號中:

  1. 調用者Bean嘗試調用目標方法,但是被生成的代理截了胡
  2. 代理根據Advice的種類(本例中是@Before Advice),對Advice首先進行調用
  3. 代理調用目標方法
  4. 返回調用結果給調用者Bean(由代理返回,沒有體現在圖中)

在使用Spring AOP的時候可能會遇到的一個問題。類似這種間接調用不會觸發Advice的原因在於調用發生在目標方法所在Bean的內部,和外面的代理對象可是沒有半毛錢的關係哦。我們可以把這個代理想象成一箇中介,只有它知道Advice的存在,調用者Bean和目標方法所在Bean知道彼此的存在,但是對於代理或者是Advice卻是一無所知的。因此,沒有通過代理的調用是絕無可能觸發Advice的邏輯的。

代理模式的應用場景還有延遲加載場景,延遲加載的思想:如果當前沒有使用這個組件時,則不需要真正地去初始化它,而是用一個代理對象去替代它的原有位置。當真正需要使用的時候,纔對它進行加載。使用代理模式實現延遲加載是很有意義的,首先從時間軸上分散系統的壓力,尤其在系統啓動時,不必完成所有的初始化工作,從而加速啓動時間;其次,對於很多真事主題而言,在軟件啓動到系統關閉的整個過程,可能都不會被調用,初始化這些數據無疑是一種資源的浪費。

假設某客戶端軟件,根據用戶請求,去數據庫查詢數據的功能。在數據庫查詢前需要獲得數據庫連接。在系統啓動時,初始化系統所有的類,此時嘗試獲得數據庫連接。當系統存在大量類似的操作時(XML解析等),所有這些初始化操作都必須疊加,使得系統很慢。爲此,使用代理模式,使用代理類,封裝對數據庫的查詢操作。當系統啓動時,初始化這個代理類,而非真實的數據庫查詢類,而代理類什麼都不做。當真正開始查詢的時候,才初始化查詢對象。

代理模式的應用場景主要還是分爲4類:

遠程代理:爲一個對象在不同地址空間提供局部代表。這樣可以隱藏一個對象存在於不同地址空間的事實,例如:老阮(MrRuan)在地點A,老李在地點B,餐廳櫃檯也在地點B,那麼老李和老軟住在一起(都在地點A住),那麼老李就是餐廳(地點B)在老軟與老李住處(地點A)的代表。

虛擬代理:是根據需要創建開銷很大的對象。通過它來存放實例化需要很長時間的真是對象,例如:老阮(MrRuan)在地點A,到餐廳櫃檯(地點B),因爲距離遠卻是很費勁,而老李剛好在這裏(地點B)上班,所以讓老李去辦是很可行的辦法。(不太恰當) 安全代理:用來控制真是對象訪問時的權限,例如:老阮跟餐廳的櫃檯MM剛分手不方便去辦理,所以需要藉助老李去完成事項的辦理。 智能代理:是指當調用真是的對象時,代理去處理另外一些事情,例如:老李幫助老阮辦理卡片激活時,順便說說老阮的好話,讓她倆能夠和好。

WebService也是應用到了代理模式,我們來看一下WebService的示例過程:

image

實現一個完整的Web服務包括以下步驟:

◆ Web服務提供者設計實現Web服務,並將調試正確後的Web服務通過Web服務中介者發佈,並在UDDI註冊中心註冊; (發佈)

◆ Web服務請求者向Web服務中介者請求特定的服務,中介者根據請求查詢UDDI註冊中心,爲請求者尋找滿足請求的服務; (發現)

◆ Web服務中介者向Web服務請求者返回滿足條件的Web服務描述信息,該描述信息用WSDL寫成,各種支持Web服務的機器都能閱讀;(發現)

◆ 利用從Web服務中介者返回的描述信息生成相應的SOAP消息,發送給Web服務提供者,以實現Web服務的調用;(綁定)

◆ Web服務提供者按SOAP消息執行相應的Web服務,並將服務結果返回給Web服務請求者。(綁定)

總之,許多都應用到了代理模式,在使用的時候認真查看原理,對代理模式加深自己的理解。

以上就是我的分享,看完的朋友記得點贊噢!想學習更多的Java技術方面的知識的朋友們,可以進我的Java高級架構師交流羣,裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料,羣號:680075317,也可以進羣一起交流,比如遇到技術瓶頸、面試不過的,大家一些交流學習!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章