学习笔记
Java基础相关
JVM内存模型及线程空间
动态代理
java并发编程
Java中Future
移动端相关
杂乱整理
开发工具相关
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一键安装命令软件列表
Java基础知识
精选网站
有声主播知识
学习笔记
有声主播入门到进阶
有声主播新手的入门练手内容推荐
DeepSeek分析喜马拉雅旗下 喜播平台 的有声主播培训
录书设备资料1
典故专辑资料整理
0B. 脚本和大纲
01. 柳赠别——灞桥烟雨中的离愁
0A. 前置准备资料
Ai大数据模型
模型整理
使用 DeepSeek 通用公式
学会这8招,让DeepSeek变得超好用!
大数据购物分析选优
Windows和Ubuntu部署DeepSeek性能差距
本地部署 Ollam+DeepSeek 探索爬坑
模型对比测试
-
+
首页
动态代理
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文件
分享
链接
类型
密码
更新密码