動態代理(通俗易懂)

程序為什么需要代理?代理長什么樣?

例子

梳理

  • 代理對象(接口):要包含被代理的對象的方法 ---Star

  • 被代理對象:要實現代理對象(接口) ---SuperStar

  • 代理工具類:創建一個代理,返回值用代理對象,參數傳被代理的對象,用Proxy代理類new一個實例,并重寫invoke方法 --- 就是代理對象要做的事情

實體類,被代理的對象

(要實現代理)


package com.dev.springBootDemo.proxy;/*** @author zhumq* @date 2024/7/2 20:51*/
public class SuperStar implements Star{private String name;public SuperStar(String name) {this.name = name;}public String sing(String singName) {System.out.println(this.name + "正在唱:" + singName);return "唱完了!謝謝大家!";}public void dance() {System.out.println(this.name + "正在跳舞中~~~" );}}
 

代理對象(接口)

要包含被代理的對象的方法

package com.dev.springBootDemo.proxy;/*** @author zhumq* @date 2024/7/2 20:56*/
public interface Star {void dance();String sing(String singName);
}

代理工具類 :

創建一個代理,返回值用代理對象,參數傳被代理的對象,用Proxy代理類new一個實例,并重寫invoke方法 --- 就是代理對象要做的事情

package com.dev.springBootDemo.proxy;
?
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
?
/*** @author zhumq* @date 2024/7/2 20:57*/
public class ProxyUtil {public static Star createProxy(SuperStar superStar) {/*** (lassLoader loader , Class<?>[] interfaces, InvocationHandler h )* 參數1:用于指定一個類加載器* 參數2:用于指定一個接口數組,因為一個代理類可以代理多個接口,所以可以指定多個接口* ? ? ? 也就是指定生成的代理長什么樣* 參數3:用于指定一個InvocationHandler對象,當調用代理類的方法時,就會自動調用InvocationHandler中的invoke方法* ? ? ? (指定InvocationHandler中的invoke方法,在調用Star接口中的方法時,就會自動執行)* ? ? ? 也就是生成的代理對象要做什么}*/Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{Star.class}, new InvocationHandler() {@Override // 回調方法public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 代理對象要做的事情// 唱歌要先租場地,跳舞要去請老師教if ("sing".equals(method.getName())) {System.out.println("代理要去做:唱歌要先租場地");} else if ("dance".equals(method.getName())) {System.out.println("代理要去做:跳舞要去請老師教");}return method.invoke(superStar, args);}});return starProxy;}
}
?

測試類:

package com.dev.springBootDemo.proxy;
?
/*** @author zhumq* @date 2024/7/2 21:16*/
public class TestProxy {public static void main(String[] args) {SuperStar superStar = new SuperStar("周杰倫");Star proxy = ProxyUtil.createProxy(superStar);System.out.println(proxy.sing("稻香"));proxy.dance();}
}
?

輸出

代理要去做:唱歌要先租場地
周杰倫正在唱:稻香
唱完了!謝謝大家!
代理要去做:跳舞要去請老師教
周杰倫正在跳舞中~~~

解決實際問題

  • UserService

  • UserServiceImpl

  • ProxyUtil

  • TestProxy

UserService

package com.dev.springBootDemo.proxy2;/*** 用戶業務接口* @author zhumq* @date 2024/7/2 21:33*/
public interface UserService {// 登錄功能void login(String loginName, String password) throws Exception;// 刪除用戶功能void deleteUser() throws Exception;// 查詢用戶功能String[] selectUsers() throws Exception;
}
?

UserServiceImpl

package com.dev.springBootDemo.proxy2;
?
/*** 用戶業務實現(面向接口編程鳥綱)* @author zhumq* @date 2024/7/2 21:35*/
public class UserServiceImpl implements UserService{@Overridepublic void login(String loginName, String password) throws Exception {
?if ("admin".equals(loginName) && "123456".equals(password)) {System.out.println("登錄成功");}else {System.out.println("登錄失敗");}Thread.sleep(1000);}
?@Overridepublic void deleteUser() throws Exception {System.out.println("刪除了10個用戶");Thread.sleep(1000);
?}
?@Overridepublic String[] selectUsers() throws Exception {System.out.println("查詢了2個用戶");String[] users = new String[]{"張三", "李四"};Thread.sleep(1000);return users;}
}
?

ProxyUtil

package com.dev.springBootDemo.proxy2;
?
import com.dev.springBootDemo.proxy.Star;
?
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
?
/*** @author zhumq* @date 2024/7/2 21:41*/
public class ProxyUtil {// 為用戶業務對象創建代理public static UserService createProxy(UserService userService) {UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if ("login".equals(method.getName()) || "deleteUser".equals(method.getName())|| "selectUsers".equals(method.getName())) {
?long startTime = System.currentTimeMillis();
?Object s = method.invoke(userService, args);
?long endTime = System.currentTimeMillis();
?System.out.println(method.getName() + "方法耗時:" + (endTime - startTime) / 1000 + "s");
?return s;} else {return method.invoke(userService, args);}}});return userServiceProxy;}
}
?

TestProxy

package com.dev.springBootDemo.proxy2;
?
import java.util.Arrays;
?
/*** @author zhumq* @date 2024/7/2 21:49*/
public class TestProxy {public static void main(String[] args) throws Exception {UserService userService = ProxyUtil.createProxy(new UserServiceImpl());
?System.out.println("----------------用戶登錄-------------------");userService.login("admin", "123456");System.out.println("----------------用戶刪除-------------------");userService.deleteUser();System.out.println("----------------用戶查詢-------------------");String[] users = userService.selectUsers();System.out.println(Arrays.toString(users));}
}

輸出:

----------------用戶登錄-------------------
登錄成功
login方法耗時:1s
----------------用戶刪除-------------------
刪除了10個用戶
deleteUser方法耗時:1s
----------------用戶查詢-------------------
查詢了2個用戶
selectUsers方法耗時:1s
[張三, 李四]

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

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

相關文章

羅克韋爾 AB 1756-OA16控制器 模塊 處理器

羅克韋爾 AB 1756-OA16該模塊是任何自動化系統的重要組成部分&#xff0c;提供對各種過程的精確控制。它被設計為易于安裝和使用&#xff0c;具有用戶友好的界面&#xff0c;允許簡單的配置和監控。 羅克韋爾 AB 1756-OA16控制器是一款為工業應用而設計的先進控制系統。它具有…

React快速入門-跟著AI學習react

React的快速入門可以遵循以下步驟進行&#xff0c;我將結合參考文章中的相關信息&#xff0c;以分點表示和歸納的形式給出詳細步驟&#xff1a; 一、React基礎知識了解 React的概念和特點&#xff1a; React是一個專注于構建用戶界面的JavaScript庫&#xff0c;采用聲明式設計…

python將多個文件夾里面的文件拷貝到一個文件夾中

網上可以搜到很多方式&#xff0c;有的好使&#xff0c;有的不好使&#xff0c;親測如下腳本可用&#xff0c;并可達到我想要的效果&#xff0c;只將多個文件夾里的文件拷貝到一個文件夾中&#xff0c;不拷貝文件夾本身&#xff0c;如果需要文件夾也拷貝打開注釋行即可 import…

初次使用GitHub教程入門

注冊一個github賬戶 訪問地址&#xff1a;https://github.com/&#xff0c;點擊右上角sign up&#xff0c;錄入以下信息&#xff0c;郵箱&#xff0c;密碼&#xff0c;賬號&#xff0c;會有郵箱驗證&#xff0c;跟著步驟來就好了 配置 本機上設置你的github的郵箱和用戶名 …

51-5 權限維持2 - 影子賬號(隱藏用戶)

權限維持技術 權限維持技術(Persistence,也稱為權限持久化)是一種能夠在系統重啟、用戶更改密碼或其他可能導致訪問中斷的情況下保持對系統訪問的技術。例如,它包括創建系統服務、利用計劃任務、修改系統啟動項或注冊表、以及映像劫持等方法。 創建影子賬戶 影子賬戶是指隱…

【管理咨詢寶藏139】某大型快消集團公司多渠道銷售管理體系方案

本報告首發于公號“管理咨詢寶藏”&#xff0c;如需閱讀完整版報告內容&#xff0c;請查閱公號“管理咨詢寶藏”。 【管理咨詢寶藏139】某大型快消集團公司多渠道銷售管理體系方案 【格式】PDF版本 【關鍵詞】羅蘭貝格、營銷咨詢、戰略規劃 【核心觀點】 - 銷售體系建設主要需…

谷粒商城學習-06-使用vagrant快速創建linux虛擬機

這一節的內容是在Windows上安裝虛擬機。 為什么要按照虛擬機呢&#xff1f; 原因是很多軟件只能在Linux下運行&#xff0c;有的雖然也可以在Windows上運行&#xff0c;但從安裝到運行會遇到很多問題&#xff0c;為這些解決這些問題花時間對于大多數人特別是初學者是沒有什么價…

數字人直播源碼開發全攻略揭秘:如何搭建自己的數字人直播平臺?

當前&#xff0c;數字人直播逐漸成為眾多中小型企業線上帶貨和品牌宣傳的不二之選&#xff0c;而艾媒研究數據也顯示&#xff0c;超五成以上的被調查群體的企業使用過虛擬人技術&#xff0c;超三成被調查群體的企業計劃使用虛擬人技術。在此背景下&#xff0c;越來越多的創業者…

android應用的持續構建CI(一)-- 總體設計

一、背景 接下里我希望通過一系列的文章&#xff0c;把android應用的構建梳理一遍&#xff0c;從總體設計到逐個環節的實現。 總體設計jenkins集成手動簽名依賴環境應用管理 二、構建流程圖 三、技術組件 jenkinsjdkgradle360加固 既然是android應用的持續構建&#xff0c…

記錄一次解決循環依賴

場景 寫權限模塊-登錄驗證這一塊的時候&#xff0c;遇到了一個比較有意思的問題&#xff0c;循環依賴: The dependencies of some of the beans in the application context form a cycle:userController defined in file xxx↓userServiceImpl defined in file xxxx ┌───…

Web3 開發者入門手冊:技能、工具和職業前景

原文&#xff1a;https://remote3.co/blog-post/how-to-become-a-web3-developer 作者&#xff1a;Paul Anderson 編譯&#xff1a;TinTinLand Web3 是 2024 年科技領域最受矚目的話題之一——Web3 令人激動的實用潛力可以跨越多個行業&#xff0c;早期采用者更有機會在未來…

TortoiseSVN 使用教程

TortoiseSVN 使用教程 1. 引言 TortoiseSVN 是一個開源的版本控制系統,它基于 Subversion(SVN)系統,為 Windows 操作系統提供了一套方便的圖形用戶界面。通過 TortoiseSVN,用戶可以輕松地管理文件的版本,進行團隊協作,以及跟蹤文件的變更歷史。本教程將詳細介紹 Torto…

亞馬遜云服務器的價格真的那么貴嗎?一年要花多少錢?

亞馬遜Web服務&#xff08;AWS&#xff09;作為全球領先的云計算平臺&#xff0c;其定價策略常常引起用戶的關注。很多人可能會問&#xff1a;"AWS真的那么貴嗎&#xff1f;"實際上&#xff0c;這個問題的答案并不是簡單的"是"或"否"&#xff0c…

【大數據綜合試驗區1008】揭秘企業數字化轉型:大數據試驗區政策數據集大公開!

今天給大家分享的是國內頂級期刊中國工業經濟2023年發布的最新期刊《政策賦能、數字生態與企業數字化轉型——基于國家大數據綜合試驗區的準自然實驗》文章中所使用到的數據集——國家大數據綜合試驗區政策數據集以及工具變量數據&#xff0c;該文章基于2009-2019年中國上市企業…

【代碼隨想錄_Day24】134. 加油站 135. 分發糖果 860. 檸檬水找零 406. 根據身高重建隊列

Day24 OK&#xff0c;今日份的打卡&#xff01;第二十四天 以下是今日份的總結加油站分發糖果檸檬水找零根據身高重建隊列 以下是今日份的總結 加油站分發糖果檸檬水找零根據身高重建隊列 今天的題目難度不低&#xff0c;而且非常的有意思&#xff0c;盡量還是寫一些簡潔代碼…

花鍵參數確定的流程是怎么樣的?

繼續花鍵的話題&#xff0c;今天跟小伙伴們一同學習一下&#xff1a;漸開線花鍵的參數確定的一般流程及基本方法。 前面有好幾篇介紹了花鍵的基本參數的概念&#xff0c;包括規格、模數、齒數、壓力角等等。以及花鍵的定心方式&#xff0c;內外花鍵的配合方式。那么這些參數的…

ARM架構 AArch64 基礎知識介紹

介紹 aarch64是 ARM 架構的 64 位版本&#xff0c;它是 ARMv8 架構的一部分&#xff0c;被設計用來提供更高的性能和更大的地址空間&#xff0c;同時保持與 32 位 ARM 架構的兼容性。AArch64 是 ARMv8 的 64 位指令集架構&#xff08;ISA&#xff09;&#xff0c;它提供了豐富的…

2023 最新版IntelliJ IDEA 2023.1創建Java Web前(vue3)后端(spring-boot3)分離 項目詳細步驟(圖文詳解)

文章目錄 &#x1f6a9; 接上篇&#x1f3f3;?&#x1f308; 項目構建所需的相關工具JavaIDEAmavenNodeJSVueVisual Studio Code &#x1f30c; 后端項目創建詳細步驟&#x1f6eb; 1、開始創建新項目&#x1f6eb; 2、輸入項目名稱、選擇項目存儲位置、項目管理工具&#xff…

昇思25天學習打卡營第4天|yulang

今天主要了解了數據集 Dataset&#xff0c;主要包含了&#xff1a;數據集加載、數據集迭代、數據集常用操作、 可隨機訪問數據集、可迭代數據集、生成器。對于生成器很好理解&#xff0c;用代碼來造數據&#xff0c;可以動態地生成數據。主要作用數據集通常被用于訓練模型

tampermonkey插件下載國家標準文件

#創作靈感# 最近在一個系統招標正文中看到了一些國家標準&#xff0c;想要把文章下載下來&#xff0c;方便查閱&#xff0c;但是“國家標準全文公開系統”網站只提供了在線預覽功能&#xff0c;沒有提供下載功能&#xff0c;但是公司又需要文件&#xff0c;在網上找了一些辦法&…