設計模式之【動態代理】

目錄

動態代理中存在的概念

JDK動態代理

代理工廠【ProxyFactory】實現【InvocationHandler】

目標類的接口【TargetInterface】

目標類【Target】實現了接口

測試類【JDKDynamicProxyTest】

CGLIB動態代理

添加Maven依賴

代理工廠【ProxyFactory】實現【MethodInterceptor】

目標類【Target】沒有實現接口?

?測試類【CGLIBDynamicProxyTest】


動態代理中存在的概念

  • 目標類、目標對象【target】
  • 代理類、代理對象【proxy】
  • 增強邏輯【advice】

JDK動態代理

  • 要求:目標類必須要實現接口
  • 原理:和目標類實現同一個接口,對目標類進行增強

代理工廠【ProxyFactory】實現【InvocationHandler】

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyFactory<T> implements InvocationHandler {// 目標對象private final T target;public ProxyFactory(T target) {this.target = target;}/*** 獲取代理對象*/@SuppressWarnings("all")public T getProxy() {// 類加載器ClassLoader classLoader = getClassLoader();// 接口Class<?>[] interfaces = getInterfaces(target);// 返回代理對象return (T) Proxy.newProxyInstance(classLoader, interfaces, this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object obj;try {// 前置增強before();obj = method.invoke(target, args);// 返回后增強afterReturning();return obj;} catch (Throwable throwable) {// 異常后增強afterThrowing();throw throwable;} finally {// 后置增強after();}}private ClassLoader getClassLoader() {return Thread.currentThread().getContextClassLoader();}private Class<?>[] getInterfaces(T target) {return target.getClass().getInterfaces();}private void before() {System.out.println("before...");}private void after() {System.out.println("after...");}private void afterThrowing() {System.out.println("afterThrowing...");}private void afterReturning() {System.out.println("afterReturning...");}
}

目標類的接口【TargetInterface】

public interface TargetInterface {void method();
}

目標類【Target】實現了接口

public class Target implements TargetInterface {public void method() {System.out.println("執行目標方法...");}
}

測試類【JDKDynamicProxyTest】

/*** 測試JDK動態代理*/
public class JDKDynamicProxyTest {public static void main(String[] args) {// 目標對象TargetInterface target = new Target();ProxyFactory<TargetInterface> proxyFactory = new ProxyFactory<>(target);// 代理對象TargetInterface proxy = proxyFactory.getProxy();// 目標對象方法執行邏輯 + 增強邏輯proxy.method();}
}

CGLIB動態代理

  • 要求:目標類非final關鍵字修飾
  • 原理:將目標類作為父類,通過子類來對父類進行增強

添加Maven依賴

<!--CGLIB依賴-->
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>

代理工廠【ProxyFactory】實現【MethodInterceptor】

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class ProxyFactory<T> implements MethodInterceptor {/*** 獲取代理對象*/@SuppressWarnings("all")public T getProxy(Class<T> cls) {Enhancer enhancer = new Enhancer();// 設置父類enhancer.setSuperclass(cls);// 設置回調enhancer.setCallback(this);// 返回創建的代理對象return (T) enhancer.create();}@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object result;try {System.out.println("前置增強...");// 調用目標對象的方法result = methodProxy.invokeSuper(o, args);System.out.println("正常返回時增強...");return result;} catch (Throwable throwable) {System.out.println("異常時增強...");throw throwable;} finally {System.out.println("后置增強...");}}
}

目標類【Target】沒有實現接口?

public class Target {public void method() {System.out.println("目標方法執行++++++++");}
}

?測試類【CGLIBDynamicProxyTest】

public class CGLIBDynamicProxyTest {public static void main(String[] args) {ProxyFactory<Target> proxyFactory = new ProxyFactory<>();// 代理對象Target proxy = proxyFactory.getProxy(Target.class);// 原始邏輯 + 增強邏輯proxy.method();}
}

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

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

相關文章

【Linux驅動-快速回顧】一次性快速回顧TTY體系知識點(新手友好)

我將遵循一條嚴格的“問題驅動”和“演進”的邏輯線索來構建整個TTY知識體系。每引入一個新概念&#xff0c;都是為了解決前一個階段出現的問題。這樣&#xff0c;你不僅能知道“是什么”&#xff0c;更能深刻理解“為什么是這樣設計的”。 第〇階段&#xff1a;最原始的需求 …

深入淺出:讓機器聽懂世界的耳朵——梅爾頻率倒譜系數(MFCCs)

深入淺出&#xff1a;讓機器聽懂世界的耳朵——梅爾頻率倒譜系數&#xff08;MFCCs&#xff09; 在人工智能的浪潮中&#xff0c;語音識別、聲紋支付、音樂推薦等技術早已融入我們的日常生活。你是否曾好奇&#xff0c;計算機是如何理解并區分各種復雜的聲音信號的&#xff1f;…

Ubuntu22.04安裝/使用Gazebo時踩的一些坑

首先&#xff0c;本人原本打算安裝gazebo11的&#xff0c;因為官方好像不支持ubuntu22.04&#xff0c;所以要通過PPA和ROS2 humble來安裝&#xff0c;安裝過程跟著教程來的&#xff0c;也就是下面這篇 ubuntu22.04安裝gazebo11&#xff08;ROS2 Humble&#xff09;-CSDN博客 …

CPT203-Software Engineering: Introduction 介紹

目錄 1.專業名詞定義 1.1計算機軟件的定義 1.2軟件系統的定義 1.3軟件工程的定義 2.軟件的失敗與成功 2.1 失敗 2.2 成功 3.軟件開發 Professional software development 3.1 分類 3.2 專業軟件開發 professional software development 3.3專業軟件開發產品特性 3.4…

診斷工程師進階篇 --- 車載診斷怎么與時俱進?

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

奧特曼論人工智能、OpenAI與創業

來自Y Combinator的YouTube視頻&#xff0c;展示了OpenAI首席執行官薩姆奧特曼分享的深刻見解。他討論了OpenAI從一個看似瘋狂的通用人工智能&#xff08;AGI&#xff09;夢想&#xff0c;如何發展成為一個全球性的現象。奧特曼強調了早期決策的關鍵性、吸引頂尖人才的策略&…

React Ref使用

受控與非受控組件 Ref 1.獲取原生dom 類組件中&#xff1a;在componentDidMount方法內使用document.getElementById的方法獲取到dom元素 1 目標dom增加ref屬性 設置為字符串 <h2 reftitleref></h2>function changeRef(){this.refs.titleref.innerHtml }2 函數組件…

地下管線安全的智能監測先鋒:智能標志樁圖像監測裝置解析?

?在城市與鄉村的地下&#xff0c;縱橫交錯的管線是能源與信息傳輸的關鍵通道。但深埋地下的電纜、燃氣管道等設施&#xff0c;因難以直觀監測&#xff0c;面臨施工誤挖、自然災害等風險。傳統防護手段力不從心&#xff0c;TLKS-PAZ01 智能標志樁圖像監測裝置的誕生&#xff0c…

Camera相機人臉識別系列專題分析之十六:人臉特征檢測FFD算法之libcvface_api.so數據結構詳細注釋解析

【關注我&#xff0c;后續持續新增專題博文&#xff0c;謝謝&#xff01;&#xff01;&#xff01;】 上一篇我們講了&#xff1a; 這一篇我們開始講&#xff1a; Camera相機人臉識別系列專題分析之十六&#xff1a;人臉特征檢測FFD算法之libcvface_api.so數據結構詳細注釋解析…

【字節跳動】數據挖掘面試題0012:數據分析、數據挖掘、數據建模的區別

文章大綱 數據分析、數據挖掘、數據建模的區別一、核心定義與目標二、技術方法差異三、應用場景對比四、三者的關聯與遞進關系五、面試應答策略 數據分析、數據挖掘、數據建模的區別 一、核心定義與目標 數據分析&#xff1a; 是對已有的數據進行收集、清洗、整理&#xff0c;并…

預警:病毒 “黑吃黑”,GitHub 開源遠控項目暗藏后門

在開源生態蓬勃發展的當下&#xff0c;黑客們也將黑手伸向了代碼共享平臺。當黑產開發者以為在共享 “行業秘笈” 時&#xff0c;殊不知已經掉入了黑客布置的陷阱 —— 看似方便的后門遠程控制源碼和游戲作弊外掛源碼等 “圈內資源”&#xff0c;實則是植入了惡意代碼的投毒誘餌…

Qt中的QProcess類

Qt中的QProcess類 QProcess 是 Qt 框架中用于啟動和控制外部進程的類&#xff0c;它屬于 QtCore 模塊。這個類提供了執行外部程序并與它們交互的功能。 一、主要功能 啟動外部程序&#xff1a;可以啟動系統上的其他可執行程序進程通信&#xff1a;通過標準輸入、輸出和錯誤流…

周任務自動化升級:N8N與多維表格無縫聯動全解析

.自動化之言&#xff1a; 在上一篇文章中&#xff0c;我們介紹了如何利用多維表格&#xff08;如飛書多維表格或Notion&#xff09;搭建一個靈活的任務管理系統。現在我們將進一步擴展這個系統&#xff0c;借助 N8N 實現周報的自動匯總與郵件發送&#xff0c;真正實現任務管理…

Go語言的web框架--gin

本章內容&#xff0c;會介紹一下gin的運用&#xff0c;以及gin框架底層的內容&#xff0c;話不多說&#xff0c;開始進入今天的主題吧&#xff01; 一.基本使用 gin框架支持前后端不分離的形式&#xff0c;也就是直接使用模板的形式。 模板是什么&#xff1f; 這里可能有同…

企業為什么需要雙因素認證?

從進入互聯網時代開始&#xff0c;密碼是我們個人日常的重要保護。但是單獨的密碼保護可能已經不再適應當前的數字化時代。密碼已經不再足夠安全最近發生的各種安全漏洞讓我重新審視網絡安全。幾行代碼可能就導致了全球數以百萬的登錄憑證被泄露。今天&#xff0c;僅僅周期性地…

Spring Boot + 本地部署大模型實現:優化與性能提升!

在Spring Boot中集成本地部署的大模型&#xff08;如LLaMA、ChatGLM等&#xff09;并進行優化&#xff0c;需要從模型選擇、推理加速、資源管理和架構設計等多方面入手。以下是完整的優化方案及實現步驟&#xff1a; 一、核心優化策略 1. 模型量化 目標&#xff1a;減少顯存占…

仿mudou庫one thread oneloop式并發服務器

前言 我們所要實現的是一個高并發服務器的組件&#xff0c;使服務器的性能更加高效&#xff0c;是一個高并發服務器的組件&#xff0c;并不包含實際的業務。 首先需要先明確我們所要實現的目標是什么 第一點&#xff0c;實現一個高并發的服務器第二點&#xff0c;在服務器的基礎…

超詳細的私有化安裝部署Dify服務以及安裝過程中問題處理

一、什么是Dify Dify 是一款開源的大語言模型(LLM) 應用開發平臺。它融合了后端即服務&#xff08;Backend as Service&#xff09;和 LLMOps 的理念&#xff0c;使開發者可以快速搭建生產級的生成式 AI 應用。即使你是非技術人員&#xff0c;也能參與到 AI 應用的定義和數據…

國產DSP,QXS320F280049,QXS320F28377D,QXS320F2800137,QXS320F28034

自定義指令集&#xff0c;自研內核架構&#xff0c;基于eclipse自研IDE&#xff0c;工具鏈&#xff0c;算法庫。 根據自研QXS320F280049&#xff0c;做了600W和2KW數字電源方案&#xff0c;1.5KW電機方案&#xff0c;目前已在市場大量投產。 QXS320F290049應用于數字電源&#…

dotnet publish 發布后的項目,例如asp.net core mvc項目如何在ubuntu中運行,并可外部訪問

復制到 Ubuntu 上的是使用 Visual Studio 或 dotnet publish 命令生成的 發布后的輸出文件&#xff08;publish output&#xff09;&#xff0c;而不是原始項目源代碼。在這種情況下&#xff0c;確實沒有 .csproj 文件&#xff0c;所以不能直接用 dotnet run 啟動。但你可以通過…