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

[Java]动态代理

Java实现动态代理

        Java中的动态代理是一种在运行时动态创建代理类和对象的机制,允许开发者在不修改原类代码的情况下,增加额外的功能。主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现。

准备要求:

1.接口:动态代理要求目标对象必须实现一个或多个接口

2.实现InvocationHandler:这是一个接口,你需要在代理类中实现它,用来定义代理对象在处理方法调用时的行为。

3.Proxy类:这是提供新代理实例的类。它包含静态方法newProxyInstance,用于在运行时创建代理对象。

实现流程:

1. 定义接口:定义一个或多个接口,这些接口将被代理类实现。

2. 实现InvocationHandler:创建一个类实现InvocationHandler接口,并在invoke方法中定义代理逻辑。

3. 创建代理对象:使用Proxy.newProxyInstance方法创建代理对象。

关系示意图:

示例:

1.首先创建被代理对象的接口:

public interface IService {public void sayHello();public void sayGoodbye();
}

2.创建该接口的实现类:

public class ServiceImpl implements IService{@Overridepublic void sayHello() {System.out.println("hello world");}@Overridepublic void sayGoodbye() {System.out.println("goodbye world");}
}

3.编写增强类(实现InvocationHandler接口的类)增强我们的接口实现类:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;//增强类
public class ServiceHandler implements InvocationHandler {//引入需要被增强类的实例对象private Object target;public ServiceHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method: " + method.getName());//通过反射机制来执行原始方法Object result = method.invoke(target, args);System.out.println("After method: " + method.getName());return result;}
}

4.客户端代码:

import java.lang.reflect.Proxy;public class Main {public static void main(String[] args) {//创建被增强类(我的接口的实现类)对象ServiceImpl service = new ServiceImpl();//创建增强类(InvocationHandler接口的实现类)对象ServiceHandler handler = new ServiceHandler(service);//生成代理对象(被增强过的IService实例对象)IService proxy = (IService) Proxy.newProxyInstance(IService.class.getClassLoader(),new Class[]{IService.class},handler);proxy.sayHello();proxy.sayGoodbye();}
}

运行结果:

        可以看到,我们成功地通过动态代理的方式对Service实现了增强。原本只会打印一句"Hello world",现在调用sayHello方法时,还会额外进行两句话地打印。在实际开发中,不一定就只是打印两句话,还可以干更多的事情。 

http://www.xdnf.cn/news/1687.html

相关文章:

  • CSS基础
  • Ubuntu系统下交叉编译iperf3
  • 项目管理:企业战略落地的引擎与未来竞争力的核心密码
  • 力扣面试150题--基本计算器
  • 如何将极狐GitLab 合并请求导出为 CSV?
  • 基于深度学习和单目测距的前车防撞及车道偏离预警系统
  • 凸优化理论记录
  • 【Rust 精进之路之第24章错误处理·实践】错误处理策略与 `anyhow`:简化应用层错误管理
  • Redis 有序集合 ZSet 深度解析教程
  • Unity3D 基于机器学习的 AI 行为树
  • QtDesigner中Label控件详解
  • uniappx 打包配置32位64位x86安装包
  • 【数据可视化-25】时尚零售销售数据集的机器学习可视化分析
  • 02_java的运行机制以及JDKJREJVM基本介绍
  • 补题【Darkness+Different Billing+Dice Game】
  • C++开发之设计模式
  • 大模型的超参数Top P是什么 ?有什么用?
  • three.js精灵及精灵材质、Shader源码分析
  • ERROR: x264 not found using pkg-config
  • 海思ISP调试记录
  • 解决 PostgreSQL 检查约束导致的数据插入异常问题
  • Rundeck 介绍及安装:自动化调度与执行工具
  • 大模型面经 | 春招、秋招算法面试常考八股文附答案(六)
  • 信息系统项目管理师_第十四章 项目沟通管理
  • NLP实战(4):使用PyTorch构建LSTM模型预测糖尿病
  • C++ std::future的使用
  • 第二章:MCP服务器分类
  • 【C语言干货】面试 | 不使用临时变量实现两个整数的交换
  • PageView 内嵌套 TabBarView 的滑动冲突
  • PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRectF)