設計模式之代理模式(上) 靜態代理與JDK動態代理

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

代理模式

  • 給某一個對象提供一個代理,并由代理對象控制對原對象的引用。

靜態代理

靜態代理是由我們編寫好的類,在程序運行之前就已經編譯好的的類,此時就叫靜態代理。 說理論還是比較懵逼的,直接上代碼:

抽象主題,可以想象成我們的業務接口。

/*** 抽象主題。* @author wushuaiping* @date 2018/3/13 下午10:13*/
public interface ISubject {/***  比如現在有個業務功能,需要開啟某項校驗。*/void enableCheck();
}

真實主題,可以想象成我們對業務接口的實現類。

/***  真實主題* @author wushuaiping* @date 2018/3/13 下午10:21*/
public class RealSubject implements ISubject {public void enableCheck() {System.out.println("我開啟了某項校驗~~");}
}

但是有一天,我突然想加個日志記錄,但是我不想去改動原有的方法。那么我們就可以使用這種方式:

/***  代理類* @author wushuaiping* @date 2018/3/13 下午10:23*/
public class ProxySubject implements ISubject{private ISubject subject;public ProxySubject(ISubject subject){super();this.subject = subject;}// 對被代理對象的方法進行增強public void enableCheck() {before();subject.enableCheck();after();}private void before(){System.out.println("我記錄一下啟動校驗前的相關日志。");}private void after(){System.out.println("我記錄一下啟動校驗后的相關日志。");}
}

我們使用靜態代理后,來試試看這種方式能不能行?測試代碼:

public class Main{public static void main(String[] args) throws ApiException {ProxySubject proxy = new ProxySubject(new RealSubject());proxy.enableCheck();}
}

運行結果:

我記錄一下啟動校驗前的相關日志
我開啟了某項校驗~~
我記錄一下啟動校驗后的相關日志。

靜態代理模式相對比較簡單,但是缺點肯定也是有的:

  1. 一個代理對象只能服務于一個類。如果有很多類需要記錄日志的話,你的一個一個去實現。。累不死你。。

  2. 代理對象必須實現接口,如上。一個字:還是累。

動態代理

這里動態代理使用的是JDK的動態代理實現的,JDK的動態代理必須是目標對象實現接口才可以。也就是相當于我們上面的業務實現類(RealSubject)。使用CGLIB就不用實現接口也可完成動態代理,但是今天時間不多了,明天還得搬磚,所以先把JDK動態代理學了,明天再學學CGLIB的動態代理。 代碼如下:

要實現動態代理;需要先去實現InvocationHandler接口,這個接口提供了invoke方法,該方法相信用過反射或者AOP的同學應該都比較熟悉,我這里就不多講了。實現了這個后我們可以調用目標方法了,但是我們需要代理的對象還不知道從何而來,所以我們還需要使用JDK提供的Proxy.newProxyInstance方法,第一個參數是目標代理類的類加載器,第二個參數是目標代理類實現的接口,第三個參數的話是目標代理類的調用處理程序就是InvokeHandler啦。用該方法可以生產代理對象。

/***  使用Java的動態代理實現* @author wushuaiping* @date 2018/3/13 下午10:43*/
public class DynamicProxy implements InvocationHandler {private Object target;public Object getProxyInstance(Object target){this.target = target;// 使用Java的獲取代理實例方法來獲取代理實例。。好繞啊。。反正就是獲取代理實例-_-return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), this);}// 增強, 調用目標方法public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();// 因為我們需要被增強的方法enableCheck是沒有返回參數的,所以不需要返回值。// 如果有返回值 Object res = method.invoke(proxy, args); return res;就可以了method.invoke(target, args);after();return null;}private void before(){System.out.println("操作之前的日志記錄~~");}private void after(){System.out.println("操作之后的日志記錄~~");}
}

Test case

public static void main(String[] args) throws ApiException {DynamicProxy proxy = new DynamicProxy();ISubject subject = (ISubject)proxy.getProxyInstance(new RealSubject());subject.enableCheck();}

運行結果:

操作之前的日志記錄~~
我開啟了某項校驗~~
操作之后的日志記錄~~

今天的設計模式算是學完啦,抽象工廠模式感覺我可能思維不夠抽象,所以到現在還沒能理解抽象工廠模式到底能干嘛?實際中有何用處?本文用于個人學習記錄,有寫的不好的地方,還請各位大佬指點一二!

good night!

轉載于:https://my.oschina.net/u/3152087/blog/1634283

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/283898.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/283898.shtml
英文地址,請注明出處:http://en.pswp.cn/news/283898.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql 分頁查詢

使用limit函數 limit關鍵字的用法: LIMIT [offset,] rows offset指定要返回的第一行的偏移量,rows第二個指定返回行的最大數目。初始行的偏移量是0(不是1)。轉載于:https://www.cnblogs.com/xping/p/6703986.html

WPF 實現更換主題色

WPF 實現更換主題色WPF 使用 WPFDevelopers.Minimal 如何更換主題色作者:WPFDevelopersOrg原文鏈接: https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal框架使用大于等于.NET40;Visual Studio 2022;項目使用 MIT 開源許可協議&a…

vue3與vue2的區別

先來說說當下市場開發使用的問題,目前2021年使用vue3開發的企業還是少,基本上都還是以vue2的形式進行開發,vue3的開發模式跟react很像,這時候有人就會想那我學vue3有用么,淦,他喵的,先別激動&am…

Spring Data REST API集成Springfox、Swagger

原文: Documenting a Spring Data REST API with Springfox and Swagger 使用Spring Date REST,你可以迅速為Spring Date repositories的創建REST API,并提供CRUD和更多功能。然而,在嚴謹的API開發過成功,您還希望擁有自動生成的最…

【系統設計】S3 對象存儲

在本文中,我們設計了一個類似于 Amazon Simple Storage Service (S3) 的對象存儲服務。S3 是 Amazon Web Services (AWS) 提供的一項服務, 它通過基于 RESTful API 的接口提供對象存儲。根據亞馬遜的報告,到 2021 年,有超過 100 萬…

轉: telnet命令學習

1.每天一個linux命令(58):telnet命令 轉自: http://www.cnblogs.com/peida/archive/2013/03/13/2956992.html telnet命令通常用來遠程登錄。telnet程序是基于TELNET協議的遠程登錄客戶端程序。Telnet協議是TCP/IP協議族中的一員&a…

禪道、碼云、coding、redmine、jira、teambition幾大敏捷開發項目管理系統試用對比體驗

作為一個軟件公司的管理人員,在項目和人員多起來后,就需要通過系統來對項目和人員進行管理。 我們是典型的軟件外包公司,專為客戶定制軟件,所以我們的業務都是項目型的。因此,在管理模式上,我們就要用所謂…

Dubbo中的SPI機制

Dubbo中的SPI機制 概述 Service Provider Interface 即 SPI,是JDK內置的一種服務提供發現機制,可以用來啟用框架擴展和替換組件。可以讓不同的廠商針對統一接口編寫不同的實現 SPI實際上是“接口策略模式配置文件”實現的動態加載機制。在系統設計中&…

JWT:擁有我,即擁有權力

Hi,這里是桑小榆。上篇文章中,我們一起探討了 OAuth 協議的原理以及授權認證流程,本次我們一起探討 jwt 令牌作為授權協議的傳輸介質。OAuth協議規范了幾個參與角色的授權標準,安全可控的授予第三方應用,第三方應用獲取…

雙十一到來之前,阿里AI設計師“魯班”1天能做4000萬張海報

相比較去年,“魯班”的設計技藝有所提升。 人工智能很大程度上便利了我們的生活,現在他們甚至還能取代了一些設計師的工作,在雙十一正式到來之前,淘寶的宣傳已經鋪天蓋地,然而很多人都沒想到,我們打開淘寶…

Appium移動自動化測試之獲取appPackage和appActivity

方法一:直接打開Appium,點擊左上角機器人圖標 選擇apk所在位置,如圖所示,這里以ContactManager.apk為例 方法二:利用dex2jar和jd-gui這兩個工具反編譯apk文件 這里仍以ContactManager.apk為例 (1)重命名ContactManager.apk為Conta…

CAD轉WPF: 關于CAD圖紙文件轉換為WPF矢量代碼文件(xaml文件)的技巧

前言:下面的文章,我將會以幾個很簡單的步驟,來演示一下通過CAD圖紙轉換為XAML代碼文件的方法,供大佬們參考。一、為了演示一個簡單的操作,我此處先打開一個空白的CAD,等下用來進行繪制點內容使用。二、自定…

python之新式類與經典類

經典類與新式類經典類:P 或 P()--深度查找,向上查父節點新式類 :P(object)---廣度查找,繼承object,新式類的方法較多轉載于:https://www.cnblogs.com/zyy98877/p/8574983.html

Flowportal-BPM——環境配置

環境配置: 一、控制面板→程序和功能→打開或不關閉Window功能→選擇選項 二、控制面板→管理工具→Internet信息服務(IIS)管理器→左側第一個→ISAPI和CGI限制→全部選為【允許】 三、控制面板→管理工具→Internet信息服務(IIS&…

一篇文章帶你搞懂什么是DevOps?

DevOps DevOps 它的英文發音是 /de’v?ps/,類似于“迪沃普斯”,一詞本身是對于 development 以及 operation 兩個詞的混合,其目的在于縮短系統開發的生命周期,在這過程中發布特性、修復bug以及更新均被緊密的結合。 簡化的含義為…

iOS 時間戳的轉換

在開發iOS程序時,有時候需要將時間格式調整成自己希望的格式,這個時候我們可以用NSDateFormatter類來處理。例如: //實例化一個NSDateFormatter對象 NSDateFormatter *dateFormatter [[NSDateFormatter alloc] init]; //設定時間格式,這里可…

微服務架構下分布式事務解決方案 —— 阿里GTS

1 微服務的發展 微服務倡導將復雜的單體應用拆分為若干個功能簡單、松耦合的服務,這樣可以降低開發難度、增強擴展性、便于敏捷開發。當前被越來越多的開發者推崇,很多互聯網行業巨頭、開源社區等都開始了微服務的討論和實踐。Hailo有160個不同服務構成&…

重要消息丨.NET Core 3.1 將于今年12月13日結束支持

點擊上方藍字關注我們(本文閱讀時間:5分鐘).NET Core 3.1 將于 2022 年 12 月 13 日結束支持。此后,Microsoft 將不再為 .NET Core 3.1 提供服務更新或技術支持。我們建議盡快遷移到 .NET 6。如果您在支持日期結束后仍在使用 .NET Core 3.1&a…

產品設計的三大原則

1.它有用嗎? 如果我們必須從這三個特性中選擇一個作為最重要的,那就是有用性。 首要的是,一個產品必須有用。如果它無用,其它任何東西都是不相關的,因為沒有人會需要它。很明顯,有用性和可享用性看上去一樣重要&#…

常用的17個運維監控系統

1. Zabbix Zabbix 作為企業級的網絡監控工具,通過從服務器,虛擬機和網絡設備收集的數據提供實時監控,自動發現,映射和可擴展等功能。 Zabbix的企業級監控軟件為用戶提供內置的Java應用服務器監控,硬件監控&#xff0c…