Java中的动态代理——介绍与使用示例
Java中的动态代理其实就是一种“代理”模式,在运行时帮我们创建一个“代理对象”,通过这个代理对象可以在不改变原本方法的情况下,做一些额外的事情,比如记录日志、检查权限等。这种代理机制非常灵活和实用,特别是在像Spring框架这种大项目中,经常用于AOP(面向切面编程)——让我们在不打扰核心业务逻辑的情况下插入一些其他功能。
1. 什么是动态代理?
首先,我们需要理解“代理”这个概念。
假设你想找一个明星签名,但明星不可能亲自和每个人打交道,于是就雇佣了一个经纪人,这个经纪人就充当了代理。你和经纪人打交道,但实际上签名的事情经纪人会去和明星沟通,完成签名工作。
Java中的动态代理也是类似的,它创建了一个代理对象,你调用这个代理对象的方法时,实际执行的可能是原本对象的方法,但在执行的前后,代理对象还可以做一些其他的事情。
2. Java动态代理的核心
在Java中,动态代理有两个核心组件:
- 代理类(Proxy Class):Java通过
Proxy类来生成代理对象,这个代理对象会代理目标对象的行为。 - InvocationHandler接口:所有被代理的方法调用,都会被转到这个接口的
invoke()方法里面去处理。你可以在invoke()方法里做任何你想做的事情,比如添加日志、修改方法的输入输出等。
3. 动态代理是怎么工作的?
要理解动态代理,先来看几个步骤:
- 目标对象:这是你想要代理的实际对象,比如一个服务类,执行某个任务。
- 代理对象:这是由Java动态生成的,它和目标对象长得一样,实现了同样的接口。你通过它来调用方法,但实际背后是代理对象把这些调用转发给了目标对象。
- 调用处理器(InvocationHandler):代理对象每次调用方法时,都会被“拦截”,实际的执行是由
InvocationHandler里的invoke()方法来决定的。在这里你可以加入自己的逻辑,比如方法前后打印日志、检查权限等,然后再调用目标对象的方法。
4. 代码示例:一步步搞懂
让我们通过一个简单的例子来理解动态代理的工作原理。
假设你有一个服务接口Service,它有一个简单的方法doSomething():
public interface Service {void doSomething();
}
然后你实现了这个接口:
public class ServiceImpl implements Service {@Overridepublic void doSomething() {System.out.println("执行一些操作");}
}
5. 如何使用动态代理?
假设你想在执行doSomething()之前和之后打印一些日志信息,通常你可能需要手动去修改代码,但这会让代码变得不容易维护。使用动态代理可以帮助你在不修改目标对象代码的情况下实现这一功能。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class DynamicProxyExample {public static void main(String[] args) {// 创建目标对象Service target = new ServiceImpl();// 使用代理对象增强功能Service proxy = (Service) Proxy.newProxyInstance(target.getClass().getClassLoader(), // 类加载器target.getClass().getInterfaces(), // 实现的接口new InvocationHandler() { // 调用处理器@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法执行前:记录日志");Object result = method.invoke(target, args); // 调用目标对象的方法System.out.println("方法执行后:记录日志");return result;}});// 通过代理对象调用方法proxy.doSomething();}
}
6. 解释代码
-
Proxy.newProxyInstance():这个方法会为你创建一个代理对象。它需要三个参数:ClassLoader:用来加载代理类的类加载器。一般使用目标对象的类加载器。Class[]:目标对象实现的接口列表。代理对象会实现这些接口。InvocationHandler:这是调用处理器,你可以定义代理对象方法的行为。
-
InvocationHandler.invoke():每次代理对象的方法被调用,实际都会进入这个invoke()方法。这里你可以在方法调用前后做一些其他的操作,比如打印日志,最后调用目标对象的方法。
7. 输出结果
运行上面的代码,你会看到这样的输出:
方法执行前:记录日志
执行一些操作
方法执行后:记录日志
这个代理对象不仅执行了doSomething()方法,还在方法前后加上了日志记录,且不需要修改ServiceImpl的代码,这就是动态代理的强大之处。
8. 动态代理的优点
- 解耦:你可以在不修改目标对象的情况下,增加额外的功能,保持代码的干净和可维护性。
- 灵活:你可以动态地决定代理对象的行为,比如在某些条件下添加不同的功能。
- 常用于AOP:比如在Spring中,动态代理经常用于AOP,帮我们处理事务、日志、安全检查等。
9. 使用场景
- 日志记录:动态代理可以在每个方法执行前后记录日志,跟踪应用的执行情况。
- 事务管理:可以在方法执行前开启事务,执行完后提交或回滚。
- 权限校验:在某些方法执行前,可以检查用户是否有权限执行该操作。
- 远程调用:通过代理对象调用远程的服务,而不需要修改业务逻辑。
Java的动态代理为我们提供了一种非常灵活、强大的方法来增强代码的功能,而不必改变现有的代码结构。
相关文章:
Java中的动态代理——介绍与使用示例
Java中的动态代理其实就是一种“代理”模式,在运行时帮我们创建一个“代理对象”,通过这个代理对象可以在不改变原本方法的情况下,做一些额外的事情,比如记录日志、检查权限等。这种代理机制非常灵活和实用,特别是在像…...
微信开发者工具:音乐小程序报错
报错信息 GET http://localhost:3000/1.mp3 net::ERR CONNECTION REFUSED (env: Windows,mp,1.06.2303220;lib:3.6.0) 原因:小程序没有直接获取本地文件,为了提高访问速度,而采用放到网络服务器中网络访问的方式获取文件内容 解决办法&#…...
P2-3与P2-4.【C语言基本数据类型、运算符和表达式】第三节与第四节
讲解视频: P2-3.【基本数据类型、运算符和表达式】第三节 P2-4.【基本数据类型、运算符和表达式】第四节 目录 必备知识与理论 任务实施 必备知识与理论 C语言中把除了控制语句和输入输出以外的几乎所有的基本操作都作为运算符处理。 其运算符和表达式数量之多&a…...
Python | Leetcode Python题解之第492题构造矩形
题目: 题解: class Solution:def constructRectangle(self, area: int) -> List[int]:w int(sqrt(area))while area % w:w - 1return [area // w, w]...
新版vs code + Vue高亮、语法自动补全插件
vs code 版本或及以上 安装以下三个插件插件 Vetur Vue语法支持。包括语法高亮、语法代码提示、语法lint检测 ESLint语法纠错 Prettier 2.左下角设置 3.进行配置 配置内容: {"editor.fontSize": 20,"window.zoomLevel": 1,"workben…...
【优选算法】(第四十五篇)
目录 地图分析(medium) 题目解析 讲解算法原理 编写代码 课程表(medium) 题目解析 讲解算法原理 编写代码 地图分析(medium) 题目解析 1.题目链接:. - 力扣(LeetCode&#…...
自闭症儿童的康复与培养:揭秘有效方法
在生命的广阔画卷中,每一个孩子都是独一无二的色彩,他们带着各自的使命和梦想,踏上人生的旅程。然而,对于自闭症儿童而言,这段旅程似乎更加崎岖和艰难。幸运的是,星贝育园康复中心如同一盏明灯,…...
rom定制系列------小米8澎湃os1.0.28安卓13客户定制固件 刷写以及界面预览
💝💝💝 小米8后置指纹版,机型代码dipper, 官方最终版为12.5.2安卓10的版本。对于一些工作室不太适用。客户需要应用在安卓13的固件。根据客户提供的固件将卡刷改为线刷。并且修改其中客户需求。去除不需要的内置应用以…...
【CTF-SHOW】Web入门 Web14 【editor泄露-详】【var/www/html目录-详】
editor泄露问题通常出现在涉及文件编辑器或脚本编辑器的题目中,尤其是在Web安全或Pwn(系统漏洞挖掘)类别中。editor泄露的本质是由于系统未能妥善处理临时文件、编辑历史或进程信息,导致攻击者可以通过某种途径获取正在编辑的敏感…...
Chrome谷歌浏览器禁止空格下翻页但可以暂停和播放视频脚本js
前提 播放某些网站的视频的时候(不能网页全屏的视频) 会产生空格下翻页但是不能暂停播放视频,解决方案:下载油猴或者脚本猫把这代码填进去 (function() {use strict;document.body.onkeydown function(event) {var e window.event || event;// 检查是否按下空格…...
【笔记】【YOLOv10图像识别】自动识别图片、视频、摄像头、电脑桌面中的花朵学习踩坑
(一)启动 创建环境python3.9 打开此环境终端 (后面的语句操作几乎都在这个终端执行) 输入up主提供的语句:pip install -r requirements.txt 1.下载pytorch网络连接超时 pytorch网址: Start Locally | P…...
H-TCP 的效率和公平性
昨晚带安孩楼下玩耍,用手机 desmos 作了一组 response curve 置于双对数坐标系: 长肥管道的优化思路都很类似,cwnd 增长快一点: BIC TCP:二分查找逼近 capacity;CUBIC TCP:上凸曲线逼近 capa…...
集群与分布式
Cluster(集群)概述 当单独一台主机无法承载现有的用户请求量;或者一台主机因为单一故障导致业务中断的时候,就可以增加服务主机数,这些主机在一起提供服务,就叫集群,而用户所看到的依然是单个的主机,用户并…...
git rebase的常用场景: 交互式变基, 变基和本地分支基于远端分支的变基
文章目录 作用应用场景场景一:交互式变基(合并同一条线上的提交记录) —— git rebase -i HEAD~2场景二:变基(合并分支) —— git rebase [其他分支名称]场景三:本地分支与远端分支的变基 作用 使git的提交记录变得更加简洁 应用场景 场景…...
HttpURLConnection构造请求体传文件
HttpURLConnection构造请求体传文件 在Java中,使用HttpURLConnection构造请求体传输文件,你需要做以下几步: 1、创建URL对象指向你想要请求的资源。 2、通过URL打开连接,转换为HttpURLConnection实例。 3、设置请求方法为POST。 …...
STM32传感器模块编程实践(九) VL53L0X激光红外测距传感器简介及驱动源码
文章目录 一.概要二.VL53L0X测距原理三.VL53L0X主要特性四.VL53L0X硬件参考设计五.模块接线说明六.模块通讯协议介绍七.光学盖玻片介绍八.STM32单片机与VL53L0模块实现距离测量实验1.硬件准备2.软件工程3.软件主要代码4.实验效果 九.小结 一.概要 VL53L0X是一款由ST࿰…...
fastjson注解说明,fastjson注解有那些?fastjson是java的json序列化和反序列化工具包
fastjson注解说明,fastjson注解有那些?fastjson是java的json序列化和反序列化工具包 包版本说明 fastjson请使用1.2.83以上版本,小于这个版本的存在漏洞。 fastjson请使用1.2.83以上版本,小于这个版本的存在漏洞。 fastjson请使用1.2.83以上版本,小于这个版本的存在漏洞…...
VIT:论文关键点解读与常见疑问
VIT贡献点: 1. 首次将 Transformer 应用于图像识别任务 核心贡献:ViT 论文的最大贡献是提出将原本用于自然语言处理(NLP)的 Transformer 架构成功应用于图像任务。传统的计算机视觉模型主要依赖卷积神经网络(CNN&…...
ArcGIS无插件加载(无偏移)在线天地图高清影像与街道地图指南
在地理信息系统(GIS)的应用中,加载高清影像与街道地图对于地图制图、影像查阅、空间数据分析等工作至关重要。天地图作为官方出品的地图服务,以其标准的数据、较快的影像更新速度等特点受到广泛欢迎。以下是如何在ArcGIS中无插件加…...
工业相机选型(自用笔记)
可参考链接: 相机和镜头选型需要注意哪些问题_靶面尺寸-CSDN博客 工业相机选型方法_ccd工业相机选型步骤-CSDN博客 1、相机 1.1 传感器类型(CCD/CMOS) CCD相机: 1)目标是运动的则优先考虑。 2)需要高质量图像,如进行…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
