网页设计工作室网站/中山网站建设公司

网页设计工作室网站,中山网站建设公司,全球著名科技网站,wordpress文章保存图片目录 代理模式 一 静态代理 一、核心作用 二、使用场景 二 动态代理 一、核心作用 二、使用场景 具体实现:(初始) 具体实现:(改进) 一、核心业务逻辑 1. 接口 MathCalculator 2. 实现类 MathCa…

目录

代理模式

一 静态代理

一、核心作用

二、使用场景

二 动态代理

一、核心作用

二、使用场景

具体实现:(初始)

具体实现:(改进)

一、核心业务逻辑

1. 接口 MathCalculator

2. 实现类 MathCalculatorImpl

二、日志工具模块

日志工具类 logUtils

三、动态代理模块

动态代理类 DynamicProxy

四、测试验证模块

测试方法 test03()


概念:AOP 面向切面编程(Aspect-Oriented Programming)

面向切面编程,能够将那些与业务无关,却为业务模块所调用的逻辑封装起来,以减少系统代码的重复度,减少模块之间的耦合度。


代理模式

对比维度静态代理动态代理
代理关系确定时机编码期间:代理类需手动编写,明确代理目标运行期间:代理类由程序动态生成,无需预定义
实现方式代理类与目标类实现相同接口(或继承目标类),并通过组合持有目标对象通过反射(JDK动态代理)或字节码生成(CGLIB)动态拦截目标对象方法
代理范围- 仅能代理同一接口/父类的类
- 需为每个目标类单独编写代理类
JDK动态代理:代理接口实现类
CGLIB:代理无接口类(非final类)
代码复杂度- 代码简单直观,适合新手
- 需手动维护代理类
- 需理解反射/字节码机制
- 框架(如Spring)可简化开发
性能- 直接调用目标方法,无反射开销
- 性能更高
JDK动态代理:反射调用性能较低
CGLIB:首次生成代理类较慢
灵活性- 扩展功能固定,仅针对特定类
- 接口变动需同步修改代理类
- 可批量代理多个类,统一添加功能(如日志、事务)
- 接口变动自动适配
典型应用场景- 代理少量固定类
- 高频调用场景(如核心服务)
- 框架级功能扩展(Spring AOP)
- 需统一管理多个类的增强逻辑

静态代理:编码期间就决定好了代理关系

定义:代理对象是目标对象的子类型,代理对象本省并不是目标对象,而是将目标作为自己的属性

优点:同一种类型的所有对象都能代理

缺点:范围太小

动态代理:运行期间才决定好了代理关系

定义:目标对象会在执行期间被动态拦截,插入指定逻辑

优点:可以代理世间万物

缺点:复杂不好写

一 静态代理

静态代理是通过手动编写一个“替身类”(代理类),在不修改原始类代码的前提下,为其添加额外功能(如日志、权限校验),使用时通过代理类间接调用原始类。

一、核心作用

  1. 控制访问:限制或增强对原始对象的访问(如权限校验)。

  2. 功能扩展:在不修改原始对象代码的前提下,添加新功能(如日志记录、性能统计)。


二、使用场景

  1. 日志记录:在方法调用前后自动记录日志。

  2. 权限校验:调用方法前检查用户权限。

  3. 延迟加载:在需要时才初始化复杂对象(如大文件加载)。

  4. 简化复杂操作:隐藏底层复杂逻辑,对外提供简洁接口。

  5. 避坑提示:如果系统中有大量需要代理的类,建议改用动态代理(如JDK动态代理或CGLIB)。

代码实现:

定义接口:

package org.example.spring02.MathMethod;public interface MathCalculator {//定义四则运算public int div(int a, int b);public int mul(int a, int b);public int sub(int a, int b);public int add(int a, int b);}

实现类:
 

package org.example.spring02.MathMethod.MIm;import org.example.spring02.MathMethod.MathCalculator;
import org.springframework.stereotype.Component;@Component
public class MathCalculatorImpl implements MathCalculator {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int sub(int a, int b) {return a - b;}@Overridepublic int mul(int a, int b) {return a * b;}@Overridepublic int div(int a, int b) {return a / b;}}

静态代理类:

package org.example.spring02.MathMethod.proxy.statics;import lombok.Data;
import org.example.spring02.MathMethod.MathCalculator;/*** 静态代理类,实现了MathCalculator接口* 本类用于在不修改原始类的情况下,增加额外的功能处理,如日志、权限校验等
*/@Data
public class CalculatorStaticProxy implements MathCalculator {// 被代理对象private MathCalculator target;public CalculatorStaticProxy(MathCalculator mc) {this.target = mc;}@Overridepublic int div(int a, int b) {//书写日志System.out.println("div被调用了,参数是:" + a + "," + b);System.out.println("div被调用了,结果是:" + target.div(a, b));return target.div(a, b);}@Overridepublic int mul(int a, int b) {System.out.println("mul被调用了,参数是:" + a + "," + b);System.out.println("mul被调用了,结果是:" + target.mul(a, b));return target.mul(a, b);}@Overridepublic int sub(int a, int b) {System.out.println("sub被调用了,参数是:" + a + "," + b);System.out.println("sub被调用了,结果是:" + target.sub(a, b));return target.sub(a, b);}@Overridepublic int add(int a, int b) {System.out.println("add被调用了,参数是:" + a + "," + b);System.out.println("add被调用了,结果是:" + target.add(a, b));return target.add(a, b);}
}

测试类:

    // JUnit测试方法,用于测试MathCalculator的功能@Testvoid test01() {// 创建MathCalculator的实例对象MathCalculator target = new MathCalculatorImpl();// 调用add方法进行加法运算,并打印结果int add1 = target.add(1, 3);System.out.println(add1);// 分隔符,用于区分不同的测试部分System.out.println("======");// 创建静态代理对象,并传入目标对象CalculatorStaticProxy calculatorStaticProxy = new CalculatorStaticProxy(target);// 通过静态代理对象调用add方法进行加法运算,并打印结果int add = calculatorStaticProxy.add(1, 3);System.out.println(add);}

运行展示:

二 动态代理

动态代理:JDK动态代理目标对象必须有接口,代理的也只是接口规定的方法

动态代理:是在运行时通过反射或字节码技术自动生成代理类,无需手动编写“替身类”,即可为多个目标对象统一添加功能(如日志、事务管理)。

拦截处理:动态代理对象在调用原生对象的方法时,通过统一的入口(如 InvocationHandler.invoke())拦截方法调用,从而实现对参数、方法执行过程和返回结果的增强或修改

一、核心作用

  1. 统一扩展功能:批量对多个类添加相同的增强逻辑。

  2. 解耦代码:将核心业务逻辑与辅助功能(如权限校验)分离。

  3. 动态适配:运行时根据需求灵活生成代理对象。


二、使用场景

  1. 框架级功能扩展:如Spring AOP(日志、事务、权限)。

  2. RPC调用:隐藏网络通信细节,让远程调用像本地调用。

  3. 接口监控:统计接口调用耗时、成功率等。

  4. Mock测试:动态生成测试用的代理对象。

1. ClassLoader loader

  • 作用
    动态代理生成的字节码需要被类加载器加载到 JVM 中。使用目标对象的类加载器可确保代理类能访问目标类及其接口。

  • 示例

// 目标对象
UserService target = new UserServiceImpl();
// 使用目标对象的类加载器
ClassLoader loader = target.getClass().getClassLoader();

2.Class<?>[] interfaces

  • 作用
    指定代理类需要实现的接口。代理对象会实现这些接口的所有方法,并将方法调用委托给 InvocationHandler

  • 示例

// 目标对象实现的接口
Class<?>[] interfaces = target.getClass().getInterfaces();

3.InvocationHandler h

  • 作用
    定义代理逻辑的核心处理器。所有通过代理对象调用的方法,都会触发 invoke() 方法,开发者可在此插入增强逻辑。

  • 示例

InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 增强逻辑(如记录日志)System.out.println("调用方法: " + method.getName());// 调用目标对象的方法return method.invoke(target, args);}
};

具体实现:(初始)

    @Testvoid test02() {// 原生对象MathCalculator target = new MathCalculatorImpl();int add1 = target.add(1, 3);System.out.println("原生对象");System.out.println(add1);//创建动态代理/*三个参数proxy:代理对象->相当于明星的代理人method:代理对象调用目标对象的方法args:方法调用传递的参数*/InvocationHandler invocationHandler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 调用目标对象的方法并返回System.out.println("动态代理InvocationHandler的invoke中定义的");System.out.println("[日志] 调用了方法: " + method.getName());System.out.println("[日志] 获得参数: " + Arrays.toString(args));return method.invoke(target, args);}};/*三个参数ClassLoader:确保代理类的正确加载。Interfaces:定义代理类的行为范围(基于接口)。InvocationHandler:实现动态代理的核心逻辑(AOP 的基础)。*/MathCalculator proxy = (MathCalculator) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),invocationHandler);int add = proxy.add(1, 3);System.out.println(add);}

具体实现:(改进)

一、核心业务逻辑

1. 接口 MathCalculator
  • 作用:定义业务契约,明确四则运算的规范。

  • 关键点

    • 声明了加减乘除四个方法。

    • 作为动态代理的接口约束(JDK动态代理必须基于接口)。

2. 实现类 MathCalculatorImpl
  • 作用:具体实现四则运算的业务逻辑。

  • 关键点

    • 使用 @Component 标注为 Spring 组件(若配合 Spring 使用)。

    • 实现了 MathCalculator 接口中的方法。

    • 是动态代理的目标对象(原生对象)。

接口

package org.example.spring02.MathMethod;public interface MathCalculator {//定义四则运算public int div(int a, int b);public int mul(int a, int b);public int sub(int a, int b);public int add(int a, int b);}

实现类

package org.example.spring02.MathMethod.MIm;import org.example.spring02.MathMethod.MathCalculator;
import org.springframework.stereotype.Component;@Component
public class MathCalculatorImpl implements MathCalculator {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int sub(int a, int b) {return a - b;}@Overridepublic int mul(int a, int b) {return a * b;}@Overridepublic int div(int a, int b) {return a / b;}}

二、日志工具模块

日志工具类 logUtils
  • 作用:提供静态方法统一管理日志格式。

  • 核心方法

    • logStart():记录方法开始执行的日志(含方法名和参数)。

    • logEnd():记录方法正常结束的日志(含结果)。

    • logException():记录方法执行异常的日志。

  • 设计亮点

    • 使用 Object... args 支持可变参数,适配不同方法的参数。

    • 通过 Arrays.toString(args) 格式化参数输出。

package org.example.spring02.log;import java.util.Arrays;public class logUtils {public static void logStart(String name , Object... args){System.out.println("开始执行方法:"+name+",参数:"+ Arrays.toString(args));}public static void logEnd(String name , Object result){System.out.println("方法:"+name+",执行结果:"+result);}public static void logException(String name , Exception e){System.out.println("方法:"+name+",执行异常:"+e.getMessage());}public static void logEnd(){System.out.println("方法执行结束");}}

三、动态代理模块

动态代理类 DynamicProxy
  • 作用:生成代理对象,为原生对象的方法调用添加日志增强逻辑。

package org.example.spring02.MathMethod.proxy.dynamic;import org.example.spring02.log.logUtils;import java.lang.reflect.Proxy;
import java.util.Arrays;public class DynamicProxy {public static  Object newProxyInstance(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxy, method, args) -> {System.out.println("动态代理开始");System.out.println("[日志] 调用了方法: " + method.getName());logUtils.logStart(method.getName(), args);System.out.println("[日志] 获得参数: " + Arrays.toString(args));return method.invoke(target, args);});}
}

四、测试验证模块

测试方法 test03()
  • 作用:验证动态代理的日志增强功能是否生效。

    @Testvoid test03(){MathCalculator o = (MathCalculator) DynamicProxy.newProxyInstance(new MathCalculatorImpl());int add = o.add(1, 3);System.out.println(add);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/72015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BGP分解实验·21——BGP选路原则之本地优先级

当使用BGP路径属性——本地优先级&#xff0c;进行路由优选时&#xff0c;优选“本地优先级”数值较大的那个。&#xff08;eBGP之间更新不携带这个属性&#xff09; 实验拓扑如下&#xff1a; 在未实现本地优先级策略前&#xff0c;先在各个BGP之间配置完成基本连接。 R1的基…

【redis】应用场景:共享会话和手机验证码

文章目录 共享会话实现思路 手机验证码实现思路伪代码实现生成验证码验证验证码 共享会话 实现思路 如果每个应用服务器&#xff0c;维护自己的会话数据&#xff0c;此时彼此之间胡共享&#xff0c;用户请求访问到不同的服务器上&#xff0c;就可能会出现一些不能正确处理的情…

通义万相 2.1 + 蓝耘算力,AI 视频生成的梦幻组合

在这个科技日新月异的时代&#xff0c;人工智能不断刷新着我们对世界的认知。一次偶然的机会&#xff0c;我借助北京蓝耘科技股份有限公司提供的算力支持&#xff0c;踏上了使用通义万相 2.1 进行 AI 视频生成的奇妙之旅。 目录 1.1初遇蓝耘科技&#xff1a; 1.2通义万相 2.1…

【Go万字洗髓经】Golang内存模型与内存分配管理

本文目录 1. 操作系统中的虚拟内存分页与进程管理虚拟内存与内存隔离 2. Golang中的内存模型内存分配流程内存单元mspan线程缓存mcache中心缓存mcentral全局堆缓存mheapheapArena空闲页索引pageAlloc 3. Go对象分配mallocgc函数tiny对象分配内存 4.结合GMP模型来看内存模型tiny…

33.HarmonyOS NEXT NumberBox 步进器高级技巧与性能优化

HarmonyOS NEXT NumberBox 步进器高级技巧与性能优化 一、高级交互设计 1. 组件联动控制 // 与Slider双向绑定 State value: number 50Slider({value: this.value,onChange: (v) > this.value v })NumberBox({value: this.value,onChange: (v) > this.value v })2. …

关于ModbusTCP/RTU协议转Ethernet/IP(CIP)协议的方案

IGT-DSER智能网关模块支持西门子、倍福(BECKHOFF)、罗克韦尔AB&#xff0c;以及三菱、欧姆龙等各种品牌的PLC之间通讯&#xff0c;支持Ethernet/IP(CIP)、Profinet(S7)&#xff0c;以及FINS、MC等工业自动化常用协议&#xff0c;同时也支持PLC与Modbus协议的工业机器人、智能仪…

【FreeRTOS】FreeRTOS操作系统在嵌入式单片机上裸机移植

目录 一 RTOS概述 二 FreeRTOS移植 三 FreeRTOS使用 四 附录 一 RTOS概述 先了解一些基础概念&#xff0c;以下内容摘自FreeRTOS官网&#xff08;FreeRTOS™ - FreeRTOS™&#xff09;&#xff1a; 【1】RTOS基础知识 实时操作系统 (RTOS) 是一种体积小巧、确定性强的计算机…

文件包含漏洞第一关

一、什么是文件包含漏洞 1.文件包含漏洞概述 和SQL注入等攻击方式一样&#xff0c;文件包含漏洞也是一种注入型漏洞&#xff0c;其本质就是输入一段用户能够控制的脚本或者代码&#xff0c;并让服务端执行。 什么叫包含呢&#xff1f;以PHP为例&#xff0c;我们常常把可重复使…

瑞芯微RK3576(1)-硬件设计

过年期间&#xff0c;趁着放假时间做了一款3576的核心板 方案是2G DDR432G emmc 引出所有IO口 关于接口方面&#xff0c;考虑了一段时间&#xff0c;最终决定使用BTB的模式&#xff0c;主要是能够出更多的IO&#xff0c;方便拆卸&#xff0c;最让我担心的是BTB的位置问题 为了…

Java 大视界 -- Java 大数据在智能医疗药品研发数据分析与决策支持中的应用(126)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

JWT的学习

1、HTTP无状态及解决方案 HTTP一种是无状态的协议&#xff0c;每次请求都是一次独立的请求&#xff0c;一次交互之后就是陌生人。 以CSDN为例&#xff0c;先登录一次&#xff0c;然后浏览器退出&#xff0c;这个时候在进入CSDN&#xff0c;按理说服务器是不知道你已经登陆了&…

SpringBoot基础Kafka示例

这里将生产者和消费者放在一个应用中 使用的Boot3.4.3 引入Kafka依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency>yml配置 spring:application:name: kafka-1#kafka…

API调试工具的无解困境:白名单、动态IP与平台设计问题

引言 你是否曾经在开发中遇到过这样的尴尬情形&#xff1a;你打开了平台的API调试工具&#xff0c;准备一番操作&#xff0c;结果却发现根本无法连接到平台&#xff1f;别急&#xff0c;问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具&#xff0c;…

【Linux篇】初识Linux指令(上篇)

Linux命令世界&#xff1a;从新手到高手的必备指南 一 Linux发展与历史1.1 Linux起源与发展1.2 Linux与Windows操作系统对比 二 Linux常用操作指令2.1 ls命令 - “List”&#xff08;列出文件)2.2 pwd指令- "打印当前工作目录"2.3 cd指令 - “Change Directory”&…

编程视界:C++命名空间

目录 命名空间 为什么要使用命名空间 什么是命名空间 命名空间的使用方式 关键点总结 命名空间的嵌套使用 匿名命名空间 跨模块调用问题 命名空间可以多次定义 总结 首先从C的hello,world程序入手&#xff0c;来认识一下C语言 #include <iostream> using name…

Excel 保护工作簿:它能解决哪些问题?如何正确使用?

在日常办公中&#xff0c;Excel 表格常常涉及多人协作、重要数据保护&#xff0c;甚至是避免误操作的情况。这时候&#xff0c;“保护工作簿”功能就能派上用场。它能有效防止他人修改表结构、删除工作表&#xff0c;甚至可以设置密码&#xff0c;确保数据的完整性和安全性。今…

推理模型对SQL理解能力的评测:DeepSeek r1、GPT-4o、Kimi k1.5和Claude 3.7 Sonnet

引言 随着大型语言模型&#xff08;LLMs&#xff09;在技术领域的应用日益广泛&#xff0c;评估这些模型在特定技术任务上的能力变得越来越重要。本研究聚焦于四款领先的推理模型——DeepSeek r1、GPT-4o、Kimi k1.5和Claude 3.7 Sonnet在SQL理解与分析方面的能力&#xff0c;…

IDEA接入阿里云百炼中免费的通义千问[2025版]

安装deepseek 上一篇文章IDEA安装deepseek最新教程2025中说明了怎么用idea安装codeGPT插件&#xff0c;并接入DeepSeek&#xff0c;无奈接入的官方api已经不能使用了&#xff0c;所以我们尝试从其他地方接入 阿里云百炼https://bailian.console.aliyun.com/ 阿里云百炼‌是阿…

010-Catch2

Catch2 一、框架简介 Catch2 是一个基于 C 的现代化单元测试框架&#xff0c;支持 TDD&#xff08;测试驱动开发&#xff09;和 BDD&#xff08;行为驱动开发&#xff09;模式。其核心优势在于&#xff1a; 单头文件设计&#xff1a;v2.x 版本仅需包含 catch.hpp 即可使用自然…

Pixelmator Pro for Mac 专业图像处理软件【媲美PS的修图】

介绍 Pixelmator Pro&#xff0c;是一款非常强大、美观且易于使用的图像编辑器&#xff0c;专为 Mac 设计。采用单窗口界面、基于机器学习的智能图像编辑、自动水平检测&#xff0c;智能快速选择及更好的修复工具等功能优点。许多非破坏性的专业编辑工具可让您进行最佳的照片处…