java的动态代理如何实现
一. JdkProxy
jdkproxy动态代理必须基于接口(interface)实现
- 接口
UserInterface.java
public interface UserService {String getUserName(String userCde);
}
- 原始实现类:
UseServiceImpl.java
public class UserServiceImpl implements UserSerice {@Overridepublic String getUserName(String userCde) {System.out.println("the name of " + userCde + "is Austin");return "Austin";}
}
- 代理类 :
UserProxyFactoryBJdk.java
public class UserProxyFactoryBJdk {public static UserService getUserServiceProxy(UserService origin) {UserService userService = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() { //动态代理实现类@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("before");Object o = method.invoke(origin, args);System.out.println("after");return o;}});return userService;}public static void main(String[] args) {UserService userService = getUserServiceProxy(new UserServiceImpl());userService.getUserName("123");}
}
![]()
执行结果:
before
the name of 123is Austin
after
二. Cglib动态代理
Cglib实现动态代理与JdkProxy不同, 是通过构建继承类实现
- 原始类
UseServiceImpl.java
public class UserServiceImpl implements UserSerice {@Overridepublic String getUserName(String userCde) {System.out.println("the name of " + userCde + "is Austin");return "Austin";}
}
- 代理类 :
UserProxyFactoryByCglib.java
public static UserServiceImpl getUserServiceProxy(UserService origin) {Enhancer enhancer = new Enhancer();// 设置debug信息System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/home/aa/dev/testfile/com/austin/meta/cxf/");// 设置父类:UserServiceImplenhancer.setSuperclass(UserServiceImpl.class);//设置代理实现逻辑enhancer.setCallback(new CglibInterCeptor() {public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("CglibInterCeptor.intercept-before");Object o = proxy.invokeSuper(obj, args);System.out.println("CglibInterCeptor.intercept-after");return o;}});UserServiceImpl userService = ((UserServiceImpl) enhancer.create());return userService;}public static void main(String[] args) {UserService userService = getUserServiceProxy(new UserServiceImpl());userService.getUserName("123");}
- 执行结果
CglibInterCeptor.intercept-before
the name of 123is Austin
CglibInterCeptor.intercept-after
三. Java动态编译
通过JavaCompiler动态编译java源文件,并将相应字节码加载到JVM中,其编译底层通过javac -d 命令进行编译
- 需要动态编译的类文件
package com.austin.meta.dynamiccompiler;
public class UserServiceImplE extends UserServiceImpl {public UserServiceImplE() {}public String getUserName(String userCde) {System.out.println("before");super.getUserName(userCde);System.out.println("after");return "Austin";}
}
- 动态编译类
public class JavaCompilerTest {private static String basePath = "";public static void main(String[] args) throws Exception{System.out.println(ClassLoader.getSystemResource(""));Class<?> userServiceImplE = compiler("UserServiceImplE");UserServiceImpl o = (UserServiceImpl)userServiceImplE.getConstructor(null).newInstance(null);o.getUserName("235");}private static Class<?> getClass(String pakcge, String className) {Class<?> clazz = null;try {clazz = Class.forName(pakcge + "." +className, true, JavaCompilerTest.class.getClassLoader());} catch (ClassNotFoundException e) {e.printStackTrace();}return clazz;}/*** 动态编译java类,并通加载到JVM*/
private static Class<?> compiler(String className) throws IOException {File javaSrcFile = new File(basePath+ "/" + className + ".java");JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);List<String> options = Arrays.asList("-d", ClassLoader.getSystemResource("").toString());JavaCompiler.CompilationTask task = compiler.getTask(null, standardFileManager, null, options, null, standardFileManager.getJavaFileObjects(javaSrcFile));Boolean isCompilerSuccess = task.call();if(!isCompilerSuccess) {return null;}Class<?> clazz = getClass("com.austin.meta.dynamiccompiler", className);return clazz;}
}
- 执行结果
before
the name of 235is Austin
after
相关文章:
java的动态代理如何实现
一. JdkProxy jdkproxy动态代理必须基于接口(interface)实现 接口UserInterface.java public interface UserService {String getUserName(String userCde); }原始实现类:UseServiceImpl.java public class UserServiceImpl implements UserSerice {Overridepub…...
Java--日志管理
日志管理 作用: 设置日志级别,决定什么日志信息应该被输出、什么日志信息应该被忽略。 基本工具 见的日志管理用具有:JDK logging(配置文件:logging.properties) 和log4j(配置文件:log4j.properties) 。…...
Pygame中Sprite类的使用2
4 让僵尸动起来 让僵尸能够动起来,也就是让僵尸从屏幕右边走到屏幕左边,此时只需要使用while循环,改变僵尸图片的x轴坐标即可,代码如下所示。 while True:screen.fill((255,255,255))z1.rect.x - 5z1.draw(screen)z1.update()if…...
排队时延与流量强度
流量强度 设R为传输速率,a表示分组到达队列的平均速率,假定所有分组都是由L比特组成的,则比特到达队列的平均速率为La。比率 L a R \frac{La}{R} RLa被成为流量强度。 根据流量强度的定义,我们可以很直观的得出以下结论&#x…...
mysql:如何设计互相关注业务场景
目录 业务场景 业务问题: 数据库表设计: like(关注表): friend(朋友表) 并发场景下,SQL语句执行逻辑 比较 A 和 B 的大小,如果 A执行下面的逻辑:<&…...
AI伦理:科技发展中的人性之声
文章目录 AI伦理的关键问题1. 隐私问题2. 公平性问题3. 自主性问题4. 伦理教育问题 隐私问题的拓展分析数据收集和滥用隐私泄露和数据安全 公平性问题的拓展分析历史偏见和算法模型可解释性 自主性问题的拓展分析自主AI决策伦理框架 伦理教育的拓展分析伦理培训 结论 …...
Direct3D光照
光照的组成 环境光:这种类型的光经其他表面反射到达物体表面,并照亮整个场景,要想以较低代价粗略模拟这类反射光,环境光是一个很好的选择 漫射光:这种类型光沿着特定的方向传播。当它到达某一表面时,将沿…...
编程语言排行榜
以下是2023年的编程语言排行榜(按照流行度排序): Python:Python一直以来都是非常受欢迎的编程语言,它简洁、易读且功能强大。在数据科学、机器学习、人工智能等领域有广泛应用。 JavaScript:作为前端开发…...
基于语雀编辑器的在线文档编辑与查看
概述 语雀是一个非常优秀的文档和知识库工具,其编辑器更是非常好用,虽无开源版本,但有编译好的可以使用。本文基于语雀编辑器实现在线文档的编辑与文章的预览。 实现效果 实现 参考语雀编辑器官方文档,其实现需要引入以下文件&…...
开箱报告,Simulink Toolbox库模块使用指南(六)——S-Fuction模块(TLC)
文章目录 前言 Target Language Compiler(TLC) C MEX S-Function模块 编写TLC文件 生成代码 Tips 分析和应用 总结 前言 见《开箱报告,Simulink Toolbox库模块使用指南(一)——powergui模块》 见《开箱报告&am…...
Kafka详解
目录 一、消息系统 1、点对点的消息系统 2、发布-订阅消息系统 二、Apache Kafka 简介 三、Apache Kafka基本原理 3.1 分布式和分区(distributed、partitioned) 3.2 副本(replicated ) 3.3 整体数据流程 3.4 消息传送机制…...
rabbitmq+springboot实现幂等性操作
文章目录 1.场景描述 1.1 场景11.2 场景2 2.原理3.实战开发 3.1 建表3.2 集成mybatis-plus3.3 集成RabbitMq 3.3.1 安装mq3.3.2 springBoot集成mq 3.4 具体实现 3.4.1 mq配置类3.4.2 生产者3.4.3 消费者 1.场景描述 消息中间件是分布式系统常用的组件,无论是异…...
ubuntu server 更改时区:上海
1. 打开终端,在命令行中以超级用户或具有sudo权限的用户身份运行以下命令: sudo dpkg-reconfigure tzdata 这会打开一个对话框,用于选择系统的时区设置。 2. 在对话框中,使用上下箭头键在地区列表中选择"Asia"&#x…...
java 整合 swagger-ui 步骤
1.在xml 中添加Swagger 相关依赖 <!-- springfox-swagger2 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><!-- springfox-swa…...
介绍两款生成神经网络架构示意图的工具:NN-SVG和PlotNeuralNet
对于神经网络架构的可视化是很有意义的,可以在很大程度上帮助到我们清晰直观地了解到整个架构,我们在前面的 PyTorch的ONNX结合MNIST手写数字数据集的应用(.pth和.onnx的转换与onnx运行时) 有介绍,可以将模型架构文件(常见的格式都可以)在线上…...
iOS IdiotAVplayer实现视频分片缓存
文章目录 IdiotAVplayer 实现视频切片缓存一 iOS视频边下边播原理一 分片下载的实现1 分片下载的思路2 IdiotAVplayer 实现架构 三 IdiotAVplayer 代码解析IdiotPlayerIdiotResourceLoaderIdiotDownLoader IdiotAVplayer 实现视频切片缓存 一 iOS视频边下边播原理 初始化AVUR…...
SpringBootWeb请求-响应
HTTP请求 前后端分离 在这种模式下,前端技术人员基于"接口文档",开发前端程序;后端技术人员也基于"接口文档",开发后端程序。 由于前后端分离,对我们后端技术人员来讲,在开发过程中&a…...
List集合详解
目录 1、集合是什么? 1.1、集合与集合之间的关系 2、List集合的特点 3、遍历集合的三种方式 3.1、foreach(增强佛如循环遍历) 3.2、for循环遍历 3.3、迭代器遍历 4、LinkedList和ArrayList的区别 4.1、为什么ArrayList查询会快一些? 4.2、为什么LinkedLi…...
投稿指南【NO.12_8】【极易投中】核心期刊投稿(组合机床与自动化加工技术)
近期有不少同学咨询投稿期刊的问题,大部分院校的研究生都有发学术论文的要求,少部分要求高的甚至需要SCI或者多篇核心期刊论文才可以毕业,但是核心期刊要求论文质量高且审稿周期长,所以本博客梳理一些计算机特别是人工智能相关的期…...
解决git无法上传大文件(50MB)
解决方法 使用LFS解决GitHub无法上传大于50MB的文件 LFS简介 Git LFS(Large File Storage)是 Git 的一个扩展,用于管理大型文件,如二进制文件、图像、音频和视频文件等。它的主要目的是解决 Git 对大型二进制文件的版本控制和存…...
【LangChain】 入门:从分步调用到链式编程
LangChain 入门:从分步调用到链式编程本文基于一段翻译助手的示例代码,讲解 LangChain 的核心概念、输出解析器的作用,以及普通写法与链式写法的对比。一、LangChain 是什么? 名字拆解缩写含义LangLanguage(语言&#…...
中国移联AI元宇宙产业委调研阿尔特汽车科技园 构建高精尖产业的“技术-场景-商业”融合生态
(央链知播 北京讯) 5月7日,中国移动通信联合会人工智能与元宇宙产业工作委员会(简称“中国移联AI与元宇宙产业委”)、中国移动通信联合会数字文化与智慧教育分会、中国通信工业协会区块链专业委员会等机构秘书长何超带…...
Midjourney Chlorophyll印相实战手册(含独家--sref权重调优表与叶脉纹理增强公式)
更多请点击: https://intelliparadigm.com 第一章:Midjourney Chlorophyll印相的技术起源与美学范式 Chlorophyll印相并非传统暗房工艺的简单复刻,而是Midjourney V6模型在跨模态语义理解基础上,对植物色素光学响应机制进行算法化…...
ARM链接器Scatter文件解析与内存布局优化
1. ARM链接器Scatter文件核心概念解析在嵌入式系统开发中,内存布局的精确控制是确保系统稳定运行的关键。ARM链接器通过Scatter文件这一强大工具,为开发者提供了细粒度的内存管理能力。Scatter文件本质上是一个描述文件,它定义了代码和数据在…...
嵌入式软件在医疗设备开发中的关键技术与实践
1. 嵌入式软件如何重塑现代医疗设备开发作为一名在医疗电子行业摸爬滚打十余年的嵌入式系统工程师,我亲眼见证了嵌入式技术如何彻底改变医疗设备的形态与功能。2008年参与第一台便携式心电监护仪开发时,设备体积还像个手提箱,如今同样功能的设…...
Qt QColumnView实战:手把手教你打造一个macOS Finder风格的文件浏览器
Qt QColumnView实战:从零构建macOS风格文件浏览器 在桌面应用开发中,文件浏览器的实现一直是开发者面临的经典挑战。传统方案往往采用QTreeView或QListView,但它们难以还原macOS Finder那种优雅的列式导航体验。这正是QColumnView的用武之地—…...
AI自主报告正常胸片:技术原理、临床价值与英国NHS实践挑战
1. 项目概述:当AI开始“读”胸片作为一名在医学影像和人工智能交叉领域摸爬滚打了十多年的从业者,我亲眼见证了AI从实验室里的新奇玩具,逐渐成长为临床医生案头一个值得信赖的“第二双眼睛”。最近,一个特别的应用场景正在全球范围…...
【限时解密】Photoshop 25.5 Beta隐藏功能+Midjourney API私有化接入指南(含已验证Webhook配置模板与错误码速查表)
更多请点击: https://intelliparadigm.com 第一章:Midjourney与Photoshop整合方案的演进逻辑与架构全景 随着生成式AI在创意工作流中的深度渗透,Midjourney与Photoshop的协同已从“图像导出→手动精修”的离散模式,演进为基于API…...
解决Modelsim SE 10.6c仿真Vivado 2019乘法器IP核的“.vhd only”难题(附完整脚本)
解决Modelsim SE 10.6c仿真Vivado 2019乘法器IP核的“.vhd only”难题(附完整脚本) 在FPGA设计流程中,Xilinx Vivado与Mentor Modelsim的组合是许多工程师的首选工具链。但当Vivado 2019生成的乘法器IP核仅提供VHDL接口文件(.vhd)时ÿ…...
OpenClaw Deck:为Steam Deck打造开源模块化工具集
1. 项目概述:一个为Steam Deck量身定制的开源工具集如果你是一位Steam Deck的深度用户,大概率经历过这样的场景:想在掌机上玩一些非Steam平台的游戏,或者想对系统进行一些深度定制,却发现官方系统虽然稳定,…...
