Spring原理之代理與動態代理模式總結(四)

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

代理模式

  • 1,什么是代理模式?
    代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。

  • 2,代理模式有什么好處?
    在某些情況下,一個客戶不想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。

  • 3,代理模式一般涉及到的角色有:

    • 抽象角色:聲明真實對象代理對象共同接口,這樣一來在任何可以使用目標對象的地方都可以使用代理對象
    • 代理角色:代理對象內部含有目標對象的引用,從而可以在任何時候操作目標對象;代理對象提供一個與目標對象相同的接口,以便可以在任何時候替代目標對象。代理對象通常在客戶端調用傳遞給目標對象之前或之后,執行某個操作,而不是單純地將調用傳遞給目標對象,同時,代理對象可以在執行真實對象操作時,附加其他的操作,相當于對真實對象進行封裝。
    • 真實角色:定義了代理對象所代表的目標對象,代理角色所代表的真實對象,是我們最終要引用的對象,定義了代理對象所代表的目標對象。
public abstract class AbstractObject {//操作public abstract void operation();
}
public class RealObject extends AbstractObject {@Overridepublic void operation() {//一些操作System.out.println("一些操作");}
}
public class ProxyObject extends AbstractObject{RealObject realObject = new RealObject();@Overridepublic void operation() {//調用目標對象之前可以做相關操作System.out.println("before");        realObject.operation();        //調用目標對象之后可以做相關操作System.out.println("after");}
}
public class Client {public static void main(String[] args) {// TODO Auto-generated method stubAbstractObject obj = new ProxyObject();obj.operation();}
}
18173245_giRn.png
  • 案例二
public interface FontProvider {Font getFont(String name);
}
public abstract class ProviderFactory {public static FontProvider getFontProvider() {return new FontProviderFromDisk();}
}
public class Main() {public static void main(String[] args) {FontProvider fontProvider = ProviderFactory.getFontProvider();Font font = fontProvider.getFont("微軟雅黑");......}
}
//現在我們希望給他加上一個緩存功能,我們可以用靜態代理來完成
public class CachedFontProvider implements FontProvider {private FontProvider fontProvider;private Map<String, Font> cached;public CachedFontProvider(FontProvider fontProvider) {this.fontProvider = fontProvider;}public Font getFont(String name) {Font font = cached.get(name);if (font == null) {font = fontProvider.getFont(name);cached.put(name, font);}return font;}
}
/* 對工廠類進行相應修改,代碼使用處不必進行任何修改。 這也是面向接口編程以及工廠模式的一個好處 */
public abstract class ProviderFactory {public static FontProvider getFontProvider() {return new CachedFontProvider(new FontProviderFromDisk());}
}
18173245_giRn.png
  • 案例三
考慮以下各種情況,有多個提供類,每個類都有getXxx(String name)方法,每個類都要加入緩存功能,使用靜態代理雖然也能實現,但是也是略顯繁瑣,需要手動一一創建代理類。
public abstract class ProviderFactory {public static FontProvider getFontProvider() {...}public static ImageProvider getImageProvider() {...}public static MusicProvider getMusicProvider() {...}......
}
使用動態代理怎么完成呢?
public class CachedProviderHandler implements InvocationHandler {private Map<String, Object> cached = new HashMap<>();private Object target;public CachedProviderHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Type[] types = method.getParameterTypes();if (method.getName().matches("get.+") && (types.length == 1) &&(types[0] == String.class)) {String key = (String) args[0];Object value = cached.get(key);if (value == null) {value = method.invoke(target, args);cached.put(key, value);}return value;}return method.invoke(target, args);}
}
public abstract class ProviderFactory {public static FontProvider getFontProvider() {Class<FontProvider> targetClass = FontProvider.class;return (FontProvider) Proxy.newProxyInstance(targetClass.getClassLoader(),new Class[] { targetClass },new CachedProviderHandler(new FontProviderFromDisk()));}
}
18173245_giRn.png

動態代理

  • 代理:本來應該自己做的事情,卻請了別人來做,被請的人就是代理對象。
    • 舉例:春季回家買票讓人代買
  • 動態代理:在程序運行過程中產生的這個對象,此對象其實就是我們剛才反射講解的內容,所以動態代理其實就是通過反射來生成一個代理

  • 在Java中java.lang.reflect包下提供了一個Proxy類和一個InvocationHandler接口,通過使用這個類和接口就可以生成動態代理對象。JDK提供的代理只能針對接口做代理。我們有更強大的代理cglib

  • Proxy類中的方法創建動態代理類對象

    • public static Object newProxyInstance(ClassLoader loader,Class
public class MyInvocationHandler implements InvocationHandler {private Object target; // 目標對象public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("權限校驗");Object result = method.invoke(target, args);System.out.println("日志記錄");return result; // 返回的是代理對象}
}
public interface StudentDao {public abstract void login();public abstract void regist();
}
public class StudentDaoImpl implements StudentDao {@Overridepublic void login() {System.out.println("登錄功能");}@Overridepublic void regist() {System.out.println("注冊功能");}
}
/* * 用戶操作接口 */
public interface UserDao {public abstract void add();public abstract void delete();public abstract void update();public abstract void find();
}
public class UserDaoImpl implements UserDao {@Overridepublic void add() {System.out.println("添加功能");}@Overridepublic void delete() {System.out.println("刪除功能");}@Overridepublic void update() {System.out.println("修改功能");}@Overridepublic void find() {System.out.println("查找功能");}
}
public class Test {public static void main(String[] args) {UserDao ud = new UserDaoImpl();ud.add();ud.delete();ud.update();ud.find();System.out.println("-----------");// 我們要創建一個動態代理對象// 我準備對ud對象做一個代理對象MyInvocationHandler handler = new MyInvocationHandler(ud);UserDao proxy = (UserDao) Proxy.newProxyInstance(ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), handler);proxy.add();proxy.delete();proxy.update();proxy.find();System.out.println("-----------");StudentDao sd = new StudentDaoImpl();MyInvocationHandler handler2 = new MyInvocationHandler(sd);StudentDao proxy2 = (StudentDao) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), handler2);proxy2.login();proxy2.regist();}
}
18173245_giRn.png



轉載于:https://my.oschina.net/u/3676262/blog/1552877

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

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

相關文章

可執行文件添加快捷方式_如何停止Windows向快捷方式文件名添加“-快捷方式”...

可執行文件添加快捷方式When you make a new shortcut in Windows, it automatically adds “- Shortcut” to the end of the shortcut’s file name. This doesn’t seem like a big deal, but they can be bothersome. Sure, you can remove the text yourself when you cre…

Red hat6.4重新安裝yum

今天在Red Hat上安裝軟件時&#xff0c;發現需要依賴軟件&#xff0c;然而在用yum指令時&#xff0c;出現了下面的錯誤&#xff1a; This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. 出現這個問題的原因是&…

使用 BenchmarkDotNet 比較指定容量的 List 的性能

我們之前提到 List 是 .NET 中常用的數據結構&#xff0c;其在存儲大量數據時&#xff0c;如果能夠指定它的初始化容量&#xff0c;就會有性能提升。這個優化的方法并不是很明顯&#xff0c;因此本文將使用 BenchmarkDotNet 庫&#xff0c;通過定量對比的方式來證明這一點。實驗…

看明星合影爭C位,學PPT中C位排版法

在娛樂圈里&#xff0c;C位是大咖位&#xff0c;是對藝人實力的最好證明&#xff0c;藝人們自然會想著去力爭C位&#xff0c;正所謂“不想當將軍的兵不是好兵&#xff0c;不想站C位的明星不是好明星”。那么&#xff0c;C位是什么意思&#xff1f;C位&#xff0c;網絡流行語&am…

javafx由淺到深的 認識(一)

javafx是一款比較新興的語言框架,隨著javafx越來越實用,估計許多程序員也會慢慢接觸它,故我在這里對它由淺到深進行介紹一下. 首先,要了解javafx,就應該先知道.xml文件的布局軟件,以往java都是通過敲代碼來進行布局的,但javafx有力新的突破,它實現了拖動方式,目前我使用的輔助軟…

linux用戶的根目錄_為什么Linux允許用戶刪除根目錄?

linux用戶的根目錄Most of the time, none of us willingly performs an action that will literally break our operating systems and force us to reinstall them. But what if such an action could easily occur even by accident on the user’s part? Today’s SuperUs…

純css實現叉號

HMTL部分 <a href"#" class"close"></a> CSS部分 .close {position: absolute;right: 32px;top: 32px;width: 32px;height: 32px; } .close:before, .close:after {position: absolute;left: 15px;content: ;height: 33px;width: 2px;backgro…

微軟跨平臺maui開發chatgpt客戶端

image什么是maui.NET 多平臺應用 UI (.NET MAUI) 是一個跨平臺框架&#xff0c;用于使用 C# 和 XAML 創建本機移動(ios,andriod)和桌面(windows,mac)應用。imagechagpt最近這玩意很火&#xff0c;由于網頁版本限制了ip&#xff0c;還得必須開代理&#xff0c; 用起來比較麻煩&a…

在Xshell 6開NumLock時按小鍵盤上的數字鍵并不能輸入數字

小鍵盤問題 在Xshell 6上用vi的時候&#xff0c;開NumLock時按小鍵盤上的數字鍵并不能輸入數字&#xff0c;而是出現一個字母然后換行&#xff08;實際上是命令模式上對應上下左右的鍵&#xff09;。解決方法 選項Terminal->Features里&#xff0c;找到Disable application …

WebP 在減少圖片體積和流量上的效果如何?—— WebP 技術實踐分享

作者 | Jackson編輯 | 尾尾 不論是 PC 還是移動端&#xff0c;圖片一直占據著頁面流量的大頭&#xff0c;在圖片的大小和質量之間如何權衡&#xff0c;成為了長期困擾開發者們的問題。而 WebP 技術的出現&#xff0c;為解決該問題提供了好的方案。本文將為大家詳細介紹 WebP 技…

chrome 固定縮放比例_您如何調整Google Chrome瀏覽器的用戶界面縮放比例?

chrome 固定縮放比例Everything can be going along nicely until a program gets a new update that suddenly turns everything into a visual mess, like scaling up the UI, for example. Is there a simple solution? Today’s SuperUser Q&A post has some helpful …

樹莓派 Raspberry Pi 更換國內源

http://www.shumeipaiba.com/wanpai/jiaocheng/16.html轉載于:https://www.cnblogs.com/Baronboy/p/9185849.html

優雅告別 2022 年,2023 年主題:敢想,就敢做!

自從工作之后&#xff0c;每年春節我都會花一天時間&#xff0c;一個人待在一個小房間&#xff0c;思考自己今年做了什么具備階段性成果的事情。然后&#xff0c;寫下明年需要執行的計劃。會寫在一個 XMind 文件里&#xff0c;記錄每一年將要執行的計劃&#xff0c;且未完成的計…

純js上傳文件 很好用

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>參數設置</title> <meta name"keywords&q…

買臺電腦,不行!去旅游一下,不行!論程序員怎么實現財務自由!

“最近讀了一本不是編程的程序員技能書《軟技能-代碼之外的生存指南》&#xff0c;全書分為 7 個篇章&#xff0c;分別是職業、自我營銷、學習、生產力、理財、健身和精神。在讀完職業、自我營銷和理財這三個篇章后&#xff0c;讓我感觸很深&#xff0c;也讓我很意外。本來以為…

java發送gmail_如何在Gmail中輕松通過電子郵件發送人群

java發送gmailMailing lists are an old tool in the email arsenal, but their implementation in Gmail isn’t immediately intuitive. Read on as we show you how to email groups using your Gmail account. 郵件列表是電子郵件庫中的一個舊工具&#xff0c;但是在Gmail中…

移動web開發相關筆記(三)

1.推薦以sublime插件的排名官網:https://packagecontrol.io/&#xff08;sublime插件官網&#xff09;2.時間算法【//總秒數var totalSecond 3671;//獲取里面的小時var hoursMath.floor(totalSecond/3600);//獲取剩下的分鐘var minuteMath.floor(totalSecond%3600/60);//獲取剩…

互聯網和IT行業越來越嚴峻,前景幾何?

楔子新冠疫情反反復復&#xff0c;互聯網和IT行業一路下滑。硅谷裁員高達10萬人。前景該何處何從呢&#xff1f;春江水暖豬先知IT行業如此的不景氣&#xff0c;自然是一些在風口上被吹起來的豬首先感受到了。他們進行的自救其實就一條:裁員&#xff0c;大量的裁員。裁員可以解決…

Asp.net MVC使用Model Binding解除Session, Cookie等依賴

上篇文章"Asp.net MVC使用Filter解除Session, Cookie等依賴"介紹了如何使用Filter來解除對于Session, Cookie的依賴。其實這個也可以通過Model Binding來達到同樣的效果。 什么是Model Binding? Model Binding的作用就是將Request請求中包含的散亂參數&#xff0c;根…

C++回聲服務器_4-UDP connect版本客戶端

針對UDP套接字調用connect函數不會與對方UDP套接字建立連接&#xff0c;只是向UDP套接字注冊目標IP和端口信息。 修改客戶端代碼 服務器代碼不需要修改&#xff0c;只需修改客戶端代碼。調用connect函數之后&#xff0c;可以調用write函數和read函數來發送、接收數據&#xff0…