本文首發於泊浮目的專欄: https://segmentfault.com/blog...
代理模式是在編程中很是常見的設計模式.筆者在面試的過程當中也常常會問到相關的問題,可是不少同窗答的並不盡人意.在這篇文章中,筆者想和你們聊聊代理模式的應用及一些實踐.程序員
先來一張圖
面試
咱們能夠很明顯的看到,代理和客戶端發生了耦合,而目標端則與客戶端解耦.spring
上文提到了一點,鬆耦合.而在任何設計模式中,他們的目的都在如下範圍內:編程
這裏提到了代碼的複用性,也能夠多嘴一句,代理模式能夠幫助咱們實現The Open Closed Principle
.segmentfault
在這裏,咱們能夠舉一個例子.Target多是一位不錯的程序員,client是一家公司.在整個招聘流程中,若是Proxy是獵頭,有些獵頭則可能會想辦法幫程序員提升身價.而若是Proxy是Hr,則可能會來殺殺價.而程序員走的流程可能一直是同樣的:設計模式
咱們能夠把不一樣的行爲(討價還價的特殊技巧)寫在不一樣的Proxy裏(HrProxy or 獵頭Proxy),而咱們的程序員只要專心走流程就好了.網絡
以Java中最經常使用的框架——Spring爲例.Spring最主要提供了2個功能:框架
而咱們知道,Spring的AOP本質上是經過代理模式來作的.接下來咱們來詳細聊聊Spring提供的4種類型的AOP支持:spa
前三種都是Spring AOP實現的變體,Spring AOP構建在動態代理基礎之上,所以,Spring對AOP的支持侷限於方法攔截。設計
而SpringAOP支持兩種模式的動態代理,JDK Proxy和cglib.當Spring發現目標被代理類實現就接口時,則用JDK Proxy來實現.
代碼大概長這樣:
//spring aop 生成的代理 public class SpringAopTargetProxy extends Target{ public void operate(){ //spring aop method1... super.operate(); //spring aop method2... } }
而AspectJ是經過編譯時編織來作的,即在編譯時插代碼進去.因此能夠認爲它基於靜態代理來作AOP.
基於以上,咱們也能夠推導出SpringAOP對於final
orstatic
方法是無效的.
call
和execution
有什麼區別呢?
以前,咱們根據代理生成的時機來區分了靜態代理和動態代理.而根據使用方式,常見則有兩類:
Adapter模式適配了兩種具備不一樣接口(API)的對象,以使它們能夠一同工做。而在Proxy模式中, Proxy角色與RealSubject角色的接口(API )是相同的(透明性)。
Decorator模式與Proxy模式在實現上很類似(好比API的一致性),不過它們的使用目的不一樣——Decorator模式的目的在於增長新的功能。而在Proxy模式中,與增長新功能相比,它更注重經過設置代理人的方式來減輕本人的工做負擔.