学习笔记
Java基础相关
JVM内存模型及线程空间
动态代理
java并发编程
Java中Future
移动端相关
杂乱整理
HarmonyOS 鸿蒙开发知识
ArkTS中如何自定义组件和复用统一样式
开发工具相关
Git cmd学习整理
Markdown用法大全集
【2023年12月】工作常用
Git如何单独合并某次提交到另一个分支
前端开发相关
Node+TypeScript相关记录
TypeScript 读写 MariaDB
Node TypeScript项目 token生成、管理及拦截校验的实现
TypeScript+Express创建和实现一个服务示例
Express接口处理器抽取注册方式
Express 实现 RESTful API
创建 TypeScript Express 项目,并配置直接用 npm start 运行
TypeScript + Express 实现文件下载接口
export 和 export default的区别
TypeScript+Express 实现用户注册和登录接口
TypeScript 和 JavaScript 中,`===` 和 `==`
CSS中的尺寸大小标准
小程序px和rpx
使用Python快速处理Excel的合并拆分
读书写作相关
一些句子01
李敖语录
罗翔老师的一些经典语句
周易相关知识
周易是对自然描述还是为自然立法
40句落寞诗词,穿透柔魂弱魄
杂玩整理
黑苹果睿频问题
基于纯Linux自己部署Nas构思
Ubuntu换源
Ubuntu挂载tf卡
Ubuntu运行Docker报错
Ubuntu安装运行Docker报错处理
官方镜像安装Docker
Docker 设置root dir 切换数据到其他存储位置
systemctl stop docker 报错
NextCloud安装ffmpeg 显示视频缩略图
Docker源不生效解决方式
Docker源不生效解决方式II——搭建docker-hub镜像
搞定群晖总Docker部署gitea启用ssh协议
MacOS一键安装命令软件列表
群晖ssl证书目录
Android通过ADB命令播放视频
Java基础知识
精选网站
有声主播知识
学习笔记
有声主播入门到进阶
有声主播新手的入门练手内容推荐
DeepSeek分析喜马拉雅旗下 喜播平台 的有声主播培训
录书设备资料1
典故专辑资料整理
0B. 脚本和大纲
01. 柳赠别——灞桥烟雨中的离愁
0A. 前置准备资料
Ai大数据模型
模型整理
使用 DeepSeek 通用公式
学会这8招,让DeepSeek变得超好用!
大数据购物分析选优
Windows和Ubuntu部署DeepSeek性能差距
本地部署 Ollam+DeepSeek 探索爬坑
模型对比测试
AI模型使用心得
小说创作需求说明书
-
+
首页
动态代理
1. ### 什么是动态代理 动态代理是Java中一种面向对象编程的技术,允许在运行时创建和使用代理对象,以实现对目标对象的间接访问和控制。它的原理是通过在运行时生成代理类来拦截对目标类的方法调用,并在适当的时候添加额外的逻辑。 2. ### 动态代理实现 在Java中,动态代理主要依赖两个关键接口:InvocationHandler和Proxy。 1. ##### InvocationHandler接口: 定义了代理对象的方法调用处理器。它包含一个invoke()方法,当代理对象的方法被调用时,该方法会被执行。在invoke()方法中,我们可以插入自定义的逻辑,例如记录日志、性能监测等。该接口需要自定义实现。 2. ##### Proxy类: 提供用于创建动态代理类和对象的静态方法。它有两个方法: - **newProxyInstance()**: 用于创建代理对象,接受一个ClassLoader对象、一个Class数组和一个InvocationHandler对象作为参数。它会返回一个实现了目标类接口的代理对象。 - **getProxyClass()**: 用于获取代理类的Class对象。 3. ### 动态代理的特点: - ##### 运行时生成: 动态代理不需要事先知道目标对象的类型,而是在运行时生成代理类。 - ##### 透明性: 代理对象与目标对象可以使用相同的接口进行交互,客户端无需关心是否使用了代理。 - ##### 动态性: 可以动态地添加、修改和删除代理行为,而无需修改目标对象的源代码。 4. ### 使用场景: - ##### AOP(面向切面编程): 动态代理可以在目标对象的方法执行前后插入额外的逻辑,例如日志记录、事务管理等。这样可以将关注点从核心业务逻辑中解耦出来,提高代码可维护性和复用性。 - ##### 代理远程对象: 通过动态代理,可以方便地在网络通信中创建和使用远程服务对象,隐藏底层网络通信的细节,简化开发流程。 - ##### 延迟加载: 动态代理可以延迟加载一些开销较大的对象,只有当真正需要时才去创建和初始化。 5. ### 示例 1. 下面是一个示例,演示如何使用动态代理实现简单的日志记录功能: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface UserService { void addUser(String username); } class UserServiceImpl implements UserService { public void addUser(String username) { System.out.println("Adding user: " + username); } } class LogInvocationHandler implements InvocationHandler { private Object target; public LogInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Method " + method.getName() + " called"); Object result = method.invoke(target, args); System.out.println("Method " + method.getName() + " finished"); return result; } } public class DynamicProxyExample { public static void main(String[] args) { UserService userService = new UserServiceImpl(); LogInvocationHandler handler = new LogInvocationHandler(userService); UserService proxy = (UserService) Proxy.newProxyInstance( UserService.class.getClassLoader(), new Class[]{UserService.class}, handler ); proxy.addUser("John Doe"); } } ``` 2. 当使用动态代理远程对象时,通常会涉及到网络通信和序列化等复杂操作。下面是一个简化的示例,展示如何使用动态代理实现远程调用: ```java import java.io.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.Socket; interface RemoteService { String getData(); } class RemoteServiceImpl implements RemoteService { public String getData() { return "Remote data"; } } class RemoteInvocationHandler implements InvocationHandler { private String host; private int port; public RemoteInvocationHandler(String host, int port) { this.host = host; this.port = port; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = new Socket(host, port); try { ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream()); outputStream.writeObject(method.getName()); // 发送方法名 outputStream.writeObject(args); // 发送方法参数 String result = (String) inputStream.readObject(); // 接收返回结果 return result; } finally { socket.close(); } } } public class DynamicProxyRemoteExample { public static void main(String[] args) { String host = "127.0.0.1"; int port = 8888; RemoteInvocationHandler handler = new RemoteInvocationHandler(host, port); RemoteService proxy = (RemoteService) Proxy.newProxyInstance( RemoteService.class.getClassLoader(), new Class[]{RemoteService.class}, handler ); String remoteData = proxy.getData(); System.out.println("Remote data: " + remoteData); } } ``` 在上述示例中,我们定义了一个RemoteService接口及其实现类RemoteServiceImpl。然后创建了一个RemoteInvocationHandler来处理远程调用,并指定远程服务的主机和端口。 通过使用Proxy.newProxyInstance()方法,我们创建了一个代理对象proxy,它会在调用方法时触发RemoteInvocationHandler的invoke()方法。在invoke()方法中,我们建立了一个Socket连接,并将方法名和参数序列化后发送到远程服务器。 远程服务器接收到请求后,根据方法名和参数执行相应的方法,并将结果序列化后返回给客户端。客户端接收到结果后打印出来。
嘿手大叔
2024年1月17日 15:25
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码