当前位置: 首页 > news >正文

【Java】Reflection反射(代理模式)

1、代理模式

        给某个对象提供一个代理对象,并由代理对象来控制其对真实对象的访问。

        Subject(抽象主题角色):定义代理类和真实主题的公告对外方法,通常设计为接口。

        RealSubject(真实主题角色):定义真正的业务实现类。

        Proxy(代理主题角色):用来代理和封装真实主题。

2、静态代理

        代理类在编译时就已经确定,每个目标类都需要对应一个代理类,代码结构相对固定。

public class Client {public static void main(String[] args) {Subject subject = new Proxy();subject.request();}
}
// 代理类(代理主题角色)
class Proxy implements Subject{private Subject target;public Proxy(){target = new RealSubject();}private void before(){System.out.println("开始执行:" + LocalDateTime.now());}@Overridepublic void request() {before();// 代理调用真实主题对象(目标对象)target.request();after();}private void after(){System.out.println("结束执行:" + LocalDateTime.now());}
}
// 目标类(真实主题角色)
class RealSubject implements Subject{@Overridepublic void request() {System.out.println("真实方法被调用,正在执行!!!");try {// 模拟耗时操作Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
// Subject(抽象主题角色)
interface Subject {void request();
}// 结果:
开始执行:2025-07-23T17:58:37.625
真实方法被调用,正在执行!!!
结束执行:2025-07-23T17:58:39.643

3、动态代理

        代理类在运行时动态生成,无需手动编写每个代理类,灵活性更高。Java 中常用的动态代理方式有 JDK 动态代理和 CGLIB 代理。

1、JDK代理

        JDK 动态代理主要涉及两个类:java.lang.reflect.Proxy 和 java.lang.reflect.InvocationHandler 我们通过编写一个调用逻辑处理器 LogHandler 类案例来提供日志增强功能,并实现 InvocationHandler 接口;在 LogHandler 中维护一个目标对象,这个对象是被代理的对象(真实主题角色);在 invoke () 方法中编写方法调用的逻辑处理。

public class Client01 {public static void main(String[] args) {// 真实主题(目标对象)UserServiceImpl userServiceTarget = new UserServiceImpl();// 获取目标对象的类加载器ClassLoader classLoader = userServiceTarget.getClass().getClassLoader();// 获取目标对象的接口列表Class[] interfaces = userServiceTarget.getClass().getInterfaces();// 日志组件(添加额外操作组件相当于Proxy)LogHandler logHandler = new LogHandler(userServiceTarget);// 创建一个代理对象// 参数1:类加载器(目标对象和代理对象的类加载器需要保持一致)// 参数2:抽象主题接口// 参数3:InvocationHandler接口实现类对象(附加行为代码的定义)IUserService userService = (IUserService) Proxy.newProxyInstance(classLoader,interfaces,logHandler);// 调用业务方法userService.select();}
}class LogHandler implements InvocationHandler {private Object target;public LogHandler(Object target){this.target = target;}private void before(){System.out.println("开始执行:" + LocalDateTime.now());}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();Object returnVale = method.invoke(target,args);after();return returnVale;}private void after(){System.out.println("结束执行:" + LocalDateTime.now());}}class UserServiceImpl implements IUserService{@Overridepublic void select() {System.out.println("查询 select");try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}@Overridepublic void update() {System.out.println("更新 update");}
}interface IUserService {void select();void update();
}// 结果:
开始执行:2025-07-23T18:38:02.468
查询 select
结束执行:2025-07-23T18:38:04.470

        动态代理我们不需要知道自己创建代理类,而是通过方法动态的创建代理对象,从而可以使        其运用更加灵活。

2、CGLIB 代理

        CGLIB是一个强大的、高性能的代码生成库,它允许运行时扩展或者修改类的接口。

        1、无需接口:可以代理灭有实现接口的类。

        2、性能较高:CGLIB使用字节码生成技术,生成代理类的效率要高于Java反射。

        3、方法拦截:通过实现MethodInterceptor接口,可以拦截需要增强的目标类的方法。

       

public class Client02 {public static void main(String[] args) {Enhancer enhancer = new Enhancer();// 设置父类(目标类): cglib基于继承的方式,创建Proxy代理对象enhancer.setSuperclass(UserService.class);// 设置拦截器enhancer.setCallback(new LogHandlerCg());// 创建代理对象UserService userService = (UserService) enhancer.create();// 通过代理对象,调用目标方法userService.select();}
}class LogHandlerCg implements MethodInterceptor{private void before(){System.out.println("开始执行:" + LocalDateTime.now());}private void after(){System.out.println("结束执行:" + LocalDateTime.now());}@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {before();Object returnValue = methodProxy.invokeSuper(o,objects);after();return returnValue;}
}class UserService{public void select(){System.out.println("查询 select");}public void update(){System.out.println("更新 update");}
}

4、总结

        代理模式是一种非常实用的设计模式,它通过引入代理对象来控制对目标对象的访问,为系统提供了更强的扩展性和灵活性。静态代理适用于简单场景,而动态代理则更适合复杂多变的场景。


文章转载自:
http://bioelectrical .ciuzn.cn
http://trencher .ciuzn.cn
http://housebroke .ciuzn.cn
http://rivet .ciuzn.cn
http://twenty .ciuzn.cn
http://bulldyker .ciuzn.cn
http://gadhelic .ciuzn.cn
http://montanan .ciuzn.cn
http://antismoking .ciuzn.cn
http://yellowish .ciuzn.cn
http://rumbustiously .ciuzn.cn
http://concentric .ciuzn.cn
http://usury .ciuzn.cn
http://aluminography .ciuzn.cn
http://unofficious .ciuzn.cn
http://weston .ciuzn.cn
http://polystyrene .ciuzn.cn
http://overfold .ciuzn.cn
http://notwithstanding .ciuzn.cn
http://buzzer .ciuzn.cn
http://plutodemocracy .ciuzn.cn
http://kerala .ciuzn.cn
http://scratchpad .ciuzn.cn
http://channels .ciuzn.cn
http://tyrannical .ciuzn.cn
http://artmobile .ciuzn.cn
http://lassa .ciuzn.cn
http://pseudoplastic .ciuzn.cn
http://harvester .ciuzn.cn
http://shoran .ciuzn.cn
http://www.dtcms.com/a/293738.html

相关文章:

  • 算法竞赛备赛——【图论】最小生成树
  • 《元素周期表》超高清PDF
  • IDEA如何管理多个Java版本。
  • STM32 基础知识 定时器【概念】
  • 基于PyTorch的多视角二维流场切片三维流场预测模型
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页-微博点赞量Top6实现
  • 19.动态路由协议基础
  • 备受关注的“Facebook Email Scraper”如何操作?
  • 开源 Arkts 鸿蒙应用 开发(十)通讯--Http
  • 腾讯云推出CodeBuddy:革新AI全栈开发体验
  • 第六章 W55MH32 UDP Multicast示例
  • 神经架构搜索革命:从动态搜索到高性能LLM的蜕变之路
  • AI 搜索引擎:让信息“长脑子”而不是“堆数据”
  • 解决 i.MX6ULL 通过 ADB 连接时权限不足问题 not in the plugdev group
  • 网络调制技术对比表
  • Numpy 库 矩阵数学运算,点积,文件读取和保存等
  • 线段树学习笔记 - 练习题(1)
  • iOS 性能监控 苹果手机后台运行与能耗采样实战指南
  • 沉浸式文旅新玩法-基于4D GS技术的真人数字人赋能VR体验升级
  • 深度相机---像素转物理尺寸
  • 【基于OpenCV的图像处理】图像预处理之二值化处理以及图像的仿射变换
  • 基于Python flask的常用AI工具功能数据分析与可视化系统设计与实现,技术包括LSTM、SVM、朴素贝叶斯三种算法,echart可视化
  • linxu CentOS 配置nginx
  • 字节 AI 编辑器 Trae 2.0 SOLO 出道! 国际版不充分指南及与国内版的对比
  • 【web页面接入Apple/google/facebook三方登录】
  • 精准扫描,驱动未来:迁移科技3D视觉系统在工业自动化中的革命性应用
  • MySQL 链接方法思考
  • 【前端】ikun-pptx编辑器前瞻问题三: pptx的图片如何提取,并在前端渲染。
  • 【LeetCode 热题 100】78. 子集——(解法三)位运算
  • (46)elasticsearch-华为云CCE无状态负载部署