Java中的代理模式
Java中的代理模式
- 1. 静态代理
- 2. JDK动态代理
- 3. CGLib动态代理
1. 静态代理
接口
public interface ICeo {void meeting(String name) throws InterruptedException;
}
目标类
public class Ceo implements ICeo{public void meeting(String name) throws InterruptedException {Thread.sleep(2000);System.out.println("和"+name+"谈成了34亿的项目");}
}
代理类
public class CeoProxy implements ICeo{private Ceo ceo;public CeoProxy(Ceo ceo) {this.ceo = ceo;}@Overridepublic void meeting(String name) throws InterruptedException {System.out.println("秘书登记来访: "+name);StopWatch stopWatch = new StopWatch();stopWatch.start();ceo.meeting(name);stopWatch.stop();double totalTimeMillis = stopWatch.getTotalTimeSeconds();System.out.println("耗时: "+totalTimeMillis);}
}
测试
public class CeoTest {public static void main(String[] args) throws InterruptedException {Ceo ceo = new Ceo();CeoProxy ceoProxy = new CeoProxy(ceo);ceoProxy.meeting("XXX");}
}
2. JDK动态代理
接口
public interface IDao {void select();
}
目标类
public class UserDao implements IDao{@Overridepublic void select() {try {Thread.sleep(2000);System.out.println("select ----");} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
动态代理类

public class JdkProxy implements InvocationHandler {private Object target;public JdkProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {StopWatch stopWatch = new StopWatch();System.out.println("前置方法");stopWatch.start();Object obj = method.invoke(target, args);stopWatch.stop();System.out.println("后置方法");System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());return obj;}
}
测试
public class DaoTest {public static void main(String[] args) {UserDao userDao = new UserDao();IDao dao = (IDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new JdkProxy(new UserDao()));dao.select();}
}
总结:
- 动态生成代理类
- 通过实现接口生成代理类(目标接口必须实现接口)
- 代理类是实现接口的方式
- 调用目标类使用反射调用
- 目标类调用本类方法只会代理一次
3. CGLib动态代理

目标类
public class ZlmDao {public void select(){try {Thread.sleep(2000);System.out.println("select ---");} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
代理类
public class CglibProxy implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {StopWatch stopWatch = new StopWatch();stopWatch.start();System.out.println("前置增强");Object result = proxy.invokeSuper(obj, args);stopWatch.stop();System.out.println("后置增强");System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());return result;}
}
测试
public class ZlmDaoTest {public static void main(String[] args) {//实例化增强器Enhancer enhancer = new Enhancer();//设置需要代理的目标类enhancer.setSuperclass(ZlmDao.class);//设置拦截对象回调的实现类enhancer.setCallback(new CglibProxy());//生成代理类ZlmDao zlmDao = (ZlmDao) enhancer.create();zlmDao.select();}
}
总结
- 通过ASM第三方框架动态代理
- 无需接口(final修饰的类和方法除外)
- 代理类通过继承目标类的方式实现代理
- 调用目标类,使用子类调用父类的方式直接调用
- invokeSuper目标类中调用本类方法会再次代理
- incoke目标类中调用本来方法只会调用一次
相关文章:
Java中的代理模式
Java中的代理模式 1. 静态代理2. JDK动态代理3. CGLib动态代理 1. 静态代理 接口 public interface ICeo {void meeting(String name) throws InterruptedException; }目标类 public class Ceo implements ICeo{public void meeting(String name) throws InterruptedExcepti…...
LeetCode每日一题——1331.数组序号转换
题目传送门 题目描述 给你一个整数数组 arr ,请你将数组中的每个元素替换为它们排序后的序号。 序号代表了一个元素有多大。序号编号的规则如下: 序号从 1 开始编号。一个元素越大,那么序号越大。如果两个元素相等,那么它们的…...
2、Tomcat介绍(下)
组件分类 在Apache Tomcat中,有几个顶级组件,它们是Tomcat的核心组件,负责整个服务器的运行和管理。这些顶级组件包括: Server(服务器):Tomcat的server.xml配置文件中的<Server>元素代表整个Tomcat服务器实例。每…...
JAVA 正则表达式(heima)
JAVA 正则表达式(heima) public class RegexDemo01 {/** 正则表达式介绍:本质来说就是一个字符串,字符串中可以指定规则,来对其他字符串进行校验。* public boolean matches(String regex):根据传入的正则表达式&#…...
布瑞特单圈绝对值旋转编码器串口数据读取
布瑞特单圈绝对值旋转编码器串口数据读取 数据手册:http://briter.net/col.jsp?id109 (2.1版本RS485说明书通信协议 单圈.pdf) 绝对式编码器为布瑞特BRT38-ROM16384-RT1,采用RS485通信。 该绝对式编码器共有5根线:红、黄、黑、绿、白 由…...
Linux第六章之vim与gcc使用
一、Linux编辑器-vim使用 vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也…...
【Golang】Golang进阶系列教程--为什么说 Go 语言字符串是不可变的?
文章目录 前言推荐阅读 前言 最近有读者留言说,平时在写代码的过程中,是会对字符串进行修改的,但网上都说 Go 语言字符串是不可变的,这是为什么呢? 这个问题本身并不困难,但对于新手来说确实容易产生困惑…...
ES开启身份认证
文章目录 X-Pack简介之前的安全方案ES开启认证ES服务升级https协议开启集群节点之间的证书认证 X-Pack简介 X-Pack是Elastic Stack扩展功能,提供安全性,警报,监视,报告,机器学习和许多其他功能。 X-Pack的发展演变&am…...
Docker安装es以及ik分词器
1、拉取镜像 docker pull elasticsearch:7.10.12、下载对应版本的ik分词、并将它们解压到ik文件夹下,如图 https://github.com/medcl/elasticsearch-analysis-ik/releases 3、在服务器上创建文件夹 mkdir /usr/elklog/elk/es mkdir /usr/elklog/elk/es/data mkdi…...
中断、进程调度、进程切换、系统调用,模式切换的那些事情
提示:风萧声动,玉壶光转,一夜鱼龙舞 文章目录 前言中断进程调度进程切换线程切换模式切换所以他们有什么关系? 前言 本文内容主要参考以下几个博文中学得 进程与线程(中)的2.2.7 进程切换VS模式切换&#…...
使用web-view实现网页端和uni-app端是数据传输
要实现这个功能 第一步:要在vue的public文件夹下面引入 <script type"text/javascript" src"https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script> 第二步:建立一个新的空的uni-app项目…...
Ajax快速入门
Ajax Ajax就是前端访问服务器端数据的一个技术 还有主要就是异步交互 就是在不刷新整页面的情况下,和服务器交换部分我也数据 比如搜索的联想技术 同步和异步的概念 一个是客户端需要等待服务器完成处理,才能进行别的事 一个是客户端不需要等待服务器处…...
Google OAuth 2 authorization - Error: redirect_uri_mismatch 400
出现这个问题,一般是因为google授权origin地址和重定向redirect_uri地址没有匹配上。 请仔细检查重定向地址的url中origin部分和授权origin部分是否能够匹配:...
Qt 中操作xml文件和JSON字符串
文章目录 1、概述1.1、xml介绍1.2、json介绍 2、xml文件增删改查2.1、写xml文件内容2.2、读xml文件内容2.3、删除xml文件内容2.4、修改xml文件内容 3、构建JSON字符串3.1、JSON字符串排版4、剪切板操作 1、概述 1.1、xml介绍 XML 指可扩展标记语言(EXtensible Mark…...
React 基础篇(二)
💻 React 基础篇(二)🏠专栏:React 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向:目前主攻…...
springboot + shiro 下载文件时浏览器提示“无法下载-没有权限”或“无法下载-没有文件”问题
springboot shiro 下载文件时浏览器提示“无法下载-没有权限”或“无法下载-没有文件”问题 1. 预期效果2. 问题描述3. 问题排查4. 解决方案5. 总结 1. 预期效果 后端编写文件下载接口,前端通过浏览器的下载将文件保存到本地。 2. 问题描述 前后端代码在不同主机…...
ChatGLM-6B 部署与 P-Tuning 微调实战-使用Pycharm实战
国产大模型ChatGLM-6B微调部署入门-使用Pycharm实战 1.ChatGLM模型介绍 ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本…...
【雕爷学编程】MicroPython动手做(11)——搭建掌控板IDE开发环境四种
为了能够打好基础,系统学习MicroPython,特地入手了二块掌控板 知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通…...
uniapp android底部弹框
uniapp android底部弹框,带有动画效果 <view class"popup_box"><view class"bottom_more" click"handleClickCancel"><image src"/static/images/rescue/icon_more.png"></image></view><…...
hashedWheelTimer类
hashedWheelTimer类 目录概述需求: 设计思路实现思路分析1.hashedWheelTimer类 拓展实现 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait …...
从零开始设计千兆交换机:基于RTL8367S/SC芯片的硬件开发包获取与核心电路设计要点
从零开始设计千兆交换机:基于RTL8367S/SC芯片的硬件开发包获取与核心电路设计要点 在当今高速网络设备开发领域,千兆交换机作为基础网络设施的核心组件,其性能与稳定性直接决定了整个网络系统的表现。对于硬件工程师而言,基于RTL8…...
DeepSeek Saga模式性能压测实录(TPS从1.2K飙升至8.6K):异步事件总线+快照版本向量的组合拳揭秘
更多请点击: https://intelliparadigm.com 第一章:DeepSeek Saga模式性能压测实录(TPS从1.2K飙升至8.6K):异步事件总线快照版本向量的组合拳揭秘 在真实生产级负载下,DeepSeek R1模型启用Saga模式后&#…...
基于Circuit Playground Express与MakeCode的阿基米德螺旋桨智能小船制作
1. 项目概述:当古老智慧遇见现代创客阿基米德螺旋,这个诞生于两千多年前的巧妙发明,最初被用来从低处向高处提水。它的核心原理简单而强大:一个旋转的螺旋面,能将流体或颗粒物沿着轴向“推”动。今天,我们不…...
从MobileNetV1到RetinaFace:轻量化主干网络在人脸检测中的架构演进与实践
1. 轻量化主干网络的演进背景与需求 在移动端和嵌入式设备上实现实时人脸检测一直是计算机视觉领域的重要挑战。传统的人脸检测算法如Viola-Jones虽然计算量小,但在复杂场景下的检测精度有限。随着深度学习技术的发展,基于卷积神经网络的人脸检测方法逐渐…...
从“瞎猜”到“精准打击”:我的Qt项目Debug效率提升笔记(附GDB命令行技巧)
从“瞎猜”到“精准打击”:我的Qt项目Debug效率提升笔记(附GDB命令行技巧) 在大型Qt/C项目中,调试往往像在迷宫中摸索——图形化界面提供了便利,但当问题隐藏在动态库或第三方代码深处时,频繁点击"下一…...
X3 PI双风扇散热外壳设计:从风道原理到3D打印实践
1. 项目缘起:为什么给X3 PI做双风扇外壳?最近折腾X3 PI这块小开发板的朋友应该不少,它性能不错,但散热一直是个让人头疼的问题。我手头这块板子,稍微跑点负载,比如编译个程序或者长时间运行服务,…...
BilibiliDown:三步搞定B站无损音频提取,构建你的专属音乐库
BilibiliDown:三步搞定B站无损音频提取,构建你的专属音乐库 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.…...
AISuperDomain:构建AI API智能网关,解决网络延迟与高可用难题
1. 项目概述与核心价值最近在折腾一些自动化脚本和本地化AI应用时,我遇到了一个挺普遍但又有点烦人的问题:如何让我的程序能稳定、高效地访问那些部署在境外的AI服务API,比如OpenAI、Claude或者一些开源的模型托管平台。直接调用?…...
通信中的拆包,残包和多线程互斥锁的注意事项。qt,c++在多线程中一定要使用全局单列互斥锁,否则肯定会崩溃,这边在读这块内存,那边要写。在网络通信中,极有可能丢包,残包,因此要做好拆包,读取,打包
使用互斥锁千万不能重复释放 mute.unlock(); mute.unlock(); 这样的写法会报错我们一定要这样使用互斥锁: // 自动锁,离开作用域自动解锁,不会拷贝锁 QMutexLocker locker(&g_CSR_Mutex);...
IDEA Diagrams保姆级教程:5分钟看懂Java类图,定位源码、分析依赖超实用
IDEA Diagrams实战指南:用类图透视Java项目架构 刚接手一个遗留Java项目时,面对层层嵌套的类关系和错综复杂的接口实现,很多开发者都会感到无从下手。这时候,IDEA内置的Diagrams功能就像一盏明灯,能够将抽象的代码结构…...
