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

java的动态代理如何实现

一. JdkProxy

jdkproxy动态代理必须基于接口(interface)实现

  1. 接口UserInterface.java
public interface UserService {String getUserName(String userCde);
}
  1. 原始实现类:UseServiceImpl.java
public class UserServiceImpl implements UserSerice {@Overridepublic String getUserName(String userCde) {System.out.println("the name of " + userCde + "is Austin");return "Austin";}
}
  1. 代理类 :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不同, 是通过构建继承类实现

  1. 原始类UseServiceImpl.java
public class UserServiceImpl implements UserSerice {@Overridepublic String getUserName(String userCde) {System.out.println("the name of " + userCde + "is Austin");return "Austin";}
}
  1. 代理类 :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");}

  1. 执行结果
    CglibInterCeptor.intercept-before
    the name of 123is Austin
    CglibInterCeptor.intercept-after

三. Java动态编译

通过JavaCompiler动态编译java源文件,并将相应字节码加载到JVM中,其编译底层通过javac -d 命令进行编译

  1. 需要动态编译的类文件
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";}
}
  1. 动态编译类
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;}
}

  1. 执行结果
    before
    the name of 235is Austin
    after

相关文章:

java的动态代理如何实现

一. JdkProxy jdkproxy动态代理必须基于接口(interface)实现 接口UserInterface.java public interface UserService {String getUserName(String userCde); }原始实现类&#xff1a;UseServiceImpl.java public class UserServiceImpl implements UserSerice {Overridepub…...

Java--日志管理

日志管理 作用&#xff1a; 设置日志级别&#xff0c;决定什么日志信息应该被输出、什么日志信息应该被忽略。 基本工具 见的日志管理用具有:JDK logging&#xff08;配置文件&#xff1a;logging.properties&#xff09; 和log4j(配置文件&#xff1a;log4j.properties) 。…...

Pygame中Sprite类的使用2

4 让僵尸动起来 让僵尸能够动起来&#xff0c;也就是让僵尸从屏幕右边走到屏幕左边&#xff0c;此时只需要使用while循环&#xff0c;改变僵尸图片的x轴坐标即可&#xff0c;代码如下所示。 while True:screen.fill((255,255,255))z1.rect.x - 5z1.draw(screen)z1.update()if…...

排队时延与流量强度

流量强度 设R为传输速率&#xff0c;a表示分组到达队列的平均速率&#xff0c;假定所有分组都是由L比特组成的&#xff0c;则比特到达队列的平均速率为La。比率 L a R \frac{La}{R} RLa​被成为流量强度。 根据流量强度的定义&#xff0c;我们可以很直观的得出以下结论&#x…...

mysql:如何设计互相关注业务场景

目录 业务场景 业务问题&#xff1a; 数据库表设计&#xff1a; like&#xff08;关注表&#xff09;&#xff1a; friend&#xff08;朋友表&#xff09; 并发场景下&#xff0c;SQL语句执行逻辑 比较 A 和 B 的大小&#xff0c;如果 A执行下面的逻辑&#xff1a;<&…...

AI伦理:科技发展中的人性之声

文章目录 AI伦理的关键问题1. 隐私问题2. 公平性问题3. 自主性问题4. 伦理教育问题 隐私问题的拓展分析数据收集和滥用隐私泄露和数据安全 公平性问题的拓展分析历史偏见和算法模型可解释性 自主性问题的拓展分析自主AI决策伦理框架 伦理教育的拓展分析伦理培训 结论 &#x1f…...

Direct3D光照

光照的组成 环境光&#xff1a;这种类型的光经其他表面反射到达物体表面&#xff0c;并照亮整个场景&#xff0c;要想以较低代价粗略模拟这类反射光&#xff0c;环境光是一个很好的选择 漫射光&#xff1a;这种类型光沿着特定的方向传播。当它到达某一表面时&#xff0c;将沿…...

编程语言排行榜

以下是2023年的编程语言排行榜&#xff08;按照流行度排序&#xff09;&#xff1a; Python&#xff1a;Python一直以来都是非常受欢迎的编程语言&#xff0c;它简洁、易读且功能强大。在数据科学、机器学习、人工智能等领域有广泛应用。 JavaScript&#xff1a;作为前端开发…...

基于语雀编辑器的在线文档编辑与查看

概述 语雀是一个非常优秀的文档和知识库工具&#xff0c;其编辑器更是非常好用&#xff0c;虽无开源版本&#xff0c;但有编译好的可以使用。本文基于语雀编辑器实现在线文档的编辑与文章的预览。 实现效果 实现 参考语雀编辑器官方文档&#xff0c;其实现需要引入以下文件&…...

开箱报告,Simulink Toolbox库模块使用指南(六)——S-Fuction模块(TLC)

文章目录 前言 Target Language Compiler&#xff08;TLC&#xff09; C MEX S-Function模块 编写TLC文件 生成代码 Tips 分析和应用 总结 前言 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;一&#xff09;——powergui模块》 见《开箱报告&am…...

Kafka详解

目录 一、消息系统 1、点对点的消息系统 2、发布-订阅消息系统 二、Apache Kafka 简介 三、Apache Kafka基本原理 3.1 分布式和分区&#xff08;distributed、partitioned&#xff09; 3.2 副本&#xff08;replicated &#xff09; 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.场景描述 消息中间件是分布式系统常用的组件&#xff0c;无论是异…...

ubuntu server 更改时区:上海

1. 打开终端&#xff0c;在命令行中以超级用户或具有sudo权限的用户身份运行以下命令&#xff1a; sudo dpkg-reconfigure tzdata 这会打开一个对话框&#xff0c;用于选择系统的时区设置。 2. 在对话框中&#xff0c;使用上下箭头键在地区列表中选择"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

对于神经网络架构的可视化是很有意义的&#xff0c;可以在很大程度上帮助到我们清晰直观地了解到整个架构&#xff0c;我们在前面的 PyTorch的ONNX结合MNIST手写数字数据集的应用(.pth和.onnx的转换与onnx运行时) 有介绍&#xff0c;可以将模型架构文件(常见的格式都可以)在线上…...

iOS IdiotAVplayer实现视频分片缓存

文章目录 IdiotAVplayer 实现视频切片缓存一 iOS视频边下边播原理一 分片下载的实现1 分片下载的思路2 IdiotAVplayer 实现架构 三 IdiotAVplayer 代码解析IdiotPlayerIdiotResourceLoaderIdiotDownLoader IdiotAVplayer 实现视频切片缓存 一 iOS视频边下边播原理 初始化AVUR…...

SpringBootWeb请求-响应

HTTP请求 前后端分离 在这种模式下&#xff0c;前端技术人员基于"接口文档"&#xff0c;开发前端程序&#xff1b;后端技术人员也基于"接口文档"&#xff0c;开发后端程序。 由于前后端分离&#xff0c;对我们后端技术人员来讲&#xff0c;在开发过程中&a…...

List集合详解

目录 1、集合是什么&#xff1f; 1.1、集合与集合之间的关系 2、List集合的特点 3、遍历集合的三种方式 3.1、foreach(增强佛如循环遍历) 3.2、for循环遍历 3.3、迭代器遍历 4、LinkedList和ArrayList的区别 4.1、为什么ArrayList查询会快一些&#xff1f; 4.2、为什么LinkedLi…...

投稿指南【NO.12_8】【极易投中】核心期刊投稿(组合机床与自动化加工技术)

近期有不少同学咨询投稿期刊的问题&#xff0c;大部分院校的研究生都有发学术论文的要求&#xff0c;少部分要求高的甚至需要SCI或者多篇核心期刊论文才可以毕业&#xff0c;但是核心期刊要求论文质量高且审稿周期长&#xff0c;所以本博客梳理一些计算机特别是人工智能相关的期…...

解决git无法上传大文件(50MB)

解决方法 使用LFS解决GitHub无法上传大于50MB的文件 LFS简介 Git LFS&#xff08;Large File Storage&#xff09;是 Git 的一个扩展&#xff0c;用于管理大型文件&#xff0c;如二进制文件、图像、音频和视频文件等。它的主要目的是解决 Git 对大型二进制文件的版本控制和存…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...