解释Java中的动态代理(Dynamic Proxy)及其用例

在Java中,动态代理(Dynamic Proxy)是一种在运行时动态创建代理类和对象的机制。它允许你在不改变原有类代码的前提下,通过代理类对原有类的方法增加额外的处理逻辑(如安全检查、事务处理、日志记录等),从而增强或改变原有类的行为。

动态代理的工作原理

动态代理主要涉及到两个核心类:InvocationHandlerProxy

  1. InvocationHandler —— 这是代理实例的调用处理程序实现的接口。代理实例的每个方法调用都会被转发到该类的invoke方法。invoke方法可以实现你想要的任何代理逻辑。

  2. Proxy —— 这是用于创建动态代理类和实例的类。它有一个名为newProxyInstance的方法,该方法接收三个参数:一个类加载器(用来加载代理类)、一组接口(代理类需要实现的接口列表)和一个InvocationHandler(当代理实例的方法被调用时,方法调用会被转发到这个调用处理程序)。newProxyInstance方法会返回一个实现了指定接口的代理实例。

动态代理的示例

假设我们有一个接口和一个实现了该接口的类:

public interface Service {void performAction();
}public class ServiceImpl implements Service {@Overridepublic void performAction() {System.out.println("Performing action in ServiceImpl");}
}

现在我们想在调用performAction前后打印日志,我们可以创建一个InvocationHandler来实现这个需求:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class LoggingHandler implements InvocationHandler {private final Object target; // 目标对象public LoggingHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method " + method.getName());Object result = method.invoke(target, args); // 调用目标对象的方法System.out.println("After method " + method.getName());return result;}public static <T> T withLogging(T target, Class<T> iface) {return (T) Proxy.newProxyInstance(iface.getClassLoader(),new Class<?>[]{iface},new LoggingHandler(target));}public static void main(String[] args) {Service service = new ServiceImpl();Service proxy = withLogging(service, Service.class);proxy.performAction(); // 调用代理对象的方法}
}

当我们运行main方法时,会看到日志输出在performAction的调用前后打印,这说明代理对象成功地在实际方法调用的前后增加了日志的额外逻辑。

动态代理的用例

  1. 日志记录:在方法调用前后记录日志,跟踪方法的调用情况,常用于调试和监控目的。

  2. 事务处理:在执行数据库操作前后发起提交或回滚,这是实现数据库事务控制的一种常见方式。

  3. 权限检查:在方法执行前检查访问权限,确保只有拥有正确权限的用户才能调用方法。

  4. 性能监控:在方法执行前后记录时间,监控方法执行所需时间。

  5. 延迟加载:当资源或组件的初始化开销较大时,使用代理类做懒加载,只有在实际需要使用这些资源时才去创建它们。

  6. 网络通信:动态代理可以方便地实现远程方法调用(Remote Method Invocation,RMI)的客户端代理,从而隐藏网络通信的细节。

总结

动态代理是Java中一个强大的技术点,可以让我们在运行时为一个或多个接口动态地创建代理实现。通过代理类的实现,我们能够在方法调用链中插入自定义逻辑,而不必修改原始对象的代码。

动态代理的灵活性开启了很多高级编程技术的可能性,特别是在企业级应用和框架中,像Spring AOP(面向方面编程)就重度依赖动态代理。在Spring AOP中,动态代理被用来实现横切关注点,比如声明式事务管理、安全、日志等。

值得注意的是,动态代理仅能代理接口中的方法,如果要代理类中的方法,可以考虑使用CGLIB、ASM等字节码操作库,这些库可以在运行时生成给定类的子类,并且在其中添加增强的代码。

动态代理与CGLIB的比较

  • 动态代理:仅能代理实现了接口的类,使用Java反射API实现。
  • CGLIB:可以代理未实现接口的类,通过字节码增强操。

CGLIB能做到动态代理无法实现的事情,即代理那些没有实现接口的类。然而,它也有自己的局限性,比如不能代理final修饰的方法,因为这些方法不能被子类覆盖。

动态代理性能注意事项

虽然动态代理提供了极高的灵活性,但它也带来了一定的性能开销。因为动态代理的实现依赖于反射API,而反射操作通常比直接的方法调用要慢。在性能要求较高的应用中,这种开销可能成为一个问题。因此,在这类应用中需要谨慎权衡使用动态代理的利弊。

对于大部分企业应用,动态代理带来的性能损失几乎可以忽略不计,尤其是当它带来的编程效率提升和系统架构上的灵活性被放在优先位置时。但是,如果遇到确实存在瓶颈的情况,可以考虑使用JVM提供的一些技术来改善,如即时编译器(JIT)的优化、使用Proxy类的静态代理版本或者直接使用底层字节码增强方式。

总结来说,动态代理是一个非常强大的中间件,使得开发者可以以非常干净和抽象的方式编写应用逻辑,同时让诸如日志记录、事务管理这样的辅助功能得以模块化和重用。在设计模式中,它实现了代理模式,让我们能够在运行时为接口创建一个具体的代理实例,从而在不修改原始类代码的前提下增加或改变类的行为。

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

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

相关文章

在为法人主体添加平衡段值时选不到相应的平衡段值

1、在为H1038公司添加平衡段值时&#xff0c;值集列表中无法选到需要的平衡段值&#xff0c;进一步对其后台取值逻辑进行分析 SELECT *FROM (SELECT FLEXVALUES.FLEX_VALUE, FLEXVALUES.DESCRIPTIONFROM FND_FLEX_VALUES_VL FLEXVALUESWHERE FLEXVALUES.FLEX_VALUE_SET_ID :1…

Digimat在电池壳体SMC复合材料成型工艺中的应用

SMC工艺介绍及挑战 SMC&#xff08;Sheet Molding Compound的缩写&#xff0c;即片状模塑料&#xff09;是一种复合材料制造工艺。该工艺可以有效地代替金属&#xff0c;实现车辆轻量化目标。该工艺不仅能够显著降低车身重量&#xff0c;而且设计灵活&#xff0c;操作简单、易…

社交媒体的探索者:探寻Facebook的发展历程

在当今数字化时代&#xff0c;社交媒体已经成为了人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为最具影响力的社交平台之一&#xff0c;其发展历程承载着无数的探索与创新。本文将深入探讨Facebook的发展历程&#xff0c;从其创立初期到如今的全球化影响&#xff0…

第 8 章 机器人底盘Arduino端电机驱动(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 8.4.4 底盘实现_03Arduino端电机驱动 自定义电机驱动的实现与上一节的编码器驱动流程类似&#xff1a; ROSA…

终于知道公司薪资为什么保密了!无意中拿到了部门薪资列表,自己身为小组长,只有28k,手下好几个35k左右,心态崩了

大家好&#xff0c;我是瑶琴呀。 一直以来&#xff0c;员工不能私下谈论薪资是职场公开的规定&#xff0c;入职的时候&#xff0c;HR 也会要求每个员工在保密薪资文件上签字。 记得在大学上职业规划课的时候&#xff0c;当时老师就给我们讲过一个案例&#xff0c;公司里小李和…

数据结构与算法学习笔记九---循环队列的表示和实现(C++)

目录 前言 1.为什么要使用循环队列 2.队列的顺序存储方式的实现 1.定义 2.队列初始化 3.销毁 4.清空队列 5.队列是否为空 6.队列长度 7.队头 8.入队 9.出队 10.遍历队列 11.完整代码 3.参考资料 前言 这篇文章介绍循环队列的表示和用法。 1.为什么要使用循环队…

详细分析Vue3中的defineExpose(附Demo)

目录 前言1. 基本知识2. Demo3. 实战 前言 其基本知识可参考官网&#xff1a;Vue3中的defineExpose 1. 基本知识 defineExpose 是 Vue 3 的 Composition API 中一个新的实用函数&#xff0c;用于在 <script setup> 语法下显式暴露组件的公共属性和方法 这在处理子组件…

OpenAI 重磅发布:ChatGPT Mac 桌面应用震撼上线!

OpenAI 重磅发布&#xff1a;ChatGPT Mac 桌面应用震撼上线&#xff01; 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff0…

51单片机:点亮一个LED灯

1.新建工程 选择AT89C52&#xff0c;在Atmel下显示的是See Microchip 并不需要添加启动文件到文件夹中。 添加main.c文件&#xff0c;c比cpp效率高&#xff0c;.asm汇编即更底层 程序编写好后 nop(); 该函数在这个头文件里面 #include <INTRINS.H> #include <R…

Java JDK下载安装教程(2024年)

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

2024 Google I/O Android 相关内容汇总

2024 Google I/O Android 相关内容汇总 本次 Google I/O 的核心虽然是 AI &#xff0c;但是 Android 也是作为主要议题出现&#xff0c; Android 部分可以简单分为产品和开发相关内容&#xff0c;接下来主要介绍这两部分的相关更新。 重点开始开发相关&#xff0c;内容不少 产…

业务系统加固和安全设备加固

业务系统加固 业务系统包含哪些系统? 业务系统漏洞面临的风险 1web风险 2漏洞扫描&#xff0c;端口扫描 3系统漏洞 4逻辑漏洞 5 信息泄露 6拒绝服务 7口令爆破 加固方式&#xff1a; 在风险加上修复 1web漏洞&#xff1a; 包括csrf,xss&#xff0c;口令破解等等 修…

koa2 + jsonwebtoken + koa-jwt:实现node token验证

一、koa token生成、验证 koa-jwt官网 https://github.com/koajs/jwt 推荐一个koa-jwt学习文档&#xff1a; https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html jsonwebtoken方法添加 const { sign, verify } require(jsonwebtoken); const secretKey …

ICode国际青少年编程竞赛- Python-4级训练场-列表综合练习

ICode国际青少年编程竞赛- Python-4级训练场-列表综合练习 1、 Flyer[3].step(1) Flyer[7].step(2) Flyer[11].step(1) for i in range(4):Flyer[i * 2].step(1) Flyer[8].step(3)for i in range(3):Dev.turnRight()Dev.step(-5)2、 for i in range(5):Flyer[i5].step(Flyer[…

JavaWeb--18 tlias-web-management 登录认证

登录认证 1 登录功能功能开发 2 登录校验2.1 问题分析2.2 会话技术CookieSession令牌技术 2.3 JWT令牌介绍生成和校验登录下发令牌 2.4 过滤器Filter拦截路径过滤器链 登录校验-Filter 2.5 拦截器InterceptorInterceptor详解执行流程 登录校验- Interceptor 3 异常处理3.1 当前…

【会议征稿】2024年机器人前沿技术与创新国际会议(FTIR 2024, 7/19-21)

2024年机器人前沿技术与创新国际会议&#xff08;FTIR 2024&#xff09;将于2024年7月19-21日在中国杭州举行。FTIR 2024聚焦前沿技术与创新&#xff0c;将把机器人领域的创新学者和专家聚集到一个共同的论坛。会议的主要目标是促进机器人的研究和开发活动&#xff0c;另一个目…

基于EBAZ4205矿板的图像处理:11阈值系数可调的图像局部阈值二值化

基于EBAZ4205矿板的图像处理&#xff1a;11阈值系数可调的图像局部阈值二值化 先看效果 还是一样拿我的pynq当模特&#xff0c;然后用usb——HDMI采集卡把输出图像采集到电脑上。 注意看右边mobelxtem中的通过串口调节的参数&#xff0c; 我这里是实现了阈值系数可调的局部阈…

利用CAD绘制角度斜线的简易指南---模大狮模型网

在CAD设计中&#xff0c;绘制角度斜线是常见的需求&#xff0c;尤其在工程、建筑等领域中。正确绘制角度斜线不仅可以提高图纸的清晰度和美观度&#xff0c;还有助于准确表达设计意图。本文将介绍如何利用CAD软件进行角度斜线的绘制&#xff0c;为您提供简明易懂的操作指南。 一…

安全设备篇——抗DDOS设备

写在前面&#xff1a;up初研究这个设备的时候以为很容易&#xff0c;毕竟ddos嘛大家都懂&#xff0c;但是实际去找资料和研究的时候发现资料少的可怜&#xff0c;再加上大家知道ddos但大多没见过&#xff0c;万幸up的老东家某普有这类设备&#xff0c;和之前的同事沟通了一下还…

实战期权:权利金=定金;无需等到期日

买方: 无需支付保证金,只需支付较低的权利金(定金)。 风险: 亏损有上限,即权利金损失;但盈利无限,以小博大。 使用场景: 大型单边行情。 行情的绝对顶部 or 底部,最好是第二次顶或者第二次抵,风险较小。 买方举例: 假如判断当前在底部,买入看涨期权call…