通过JDK动态代理类实现一个类中多种方法的不同增强
1.为什么说JDK动态代理必须要实现当前父接口才能使用
JDK动态代理是基于接口的代理,它要求目标类(被代理的类)必须实现一个或多个接口。这是因为JDK动态代理是通过创建目标类的接口的代理对象来实现的,代理对象实现了目标接口,并在方法调用时委托给InvocationHandler中的invoke方法来处理。
在JDK动态代理中,Proxy类的newProxyInstance方法接受一个ClassLoader,一组接口和一个InvocationHandler,然后生成一个代理类的实例。这个代理类实例实现了指定的接口,并将方法调用委托给InvocationHandler中的invoke方法。
自我结论:可能是因为比如生成的$Proxy代理类如果没有父接口 那他内部也不知道通过InvocationHandler来调用谁来进行增强了 还有就是可能有一些决策问题。
2.JDK动态代理的$Proxy实现
Cat父接口
//父接口
interface Cat {
//开车
void drive();
//下车
void off();
}
interface InvocationHandler {
//代理类,代理方法,代理方法参数
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
class $Proxy0 implements Cat {
private InvocationHandler invocationHandler;
private Map<String, Method> methods;
public $Proxy0(InvocationHandler invocationHandler) {
this.invocationHandler = invocationHandler;
this.methods = new HashMap<>();
try {
methods.put("drive", Cat.class.getMethod("drive"));
methods.put("off", Cat.class.getMethod("off"));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
@Override
public void drive() {
try {
invocationHandler.invoke(this, methods.get("drive"), new Object[0]);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
@Override
public void off() {
try {
invocationHandler.invoke(this, methods.get("off"), new Object[0]);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
class CustomLogicHandler implements InvocationHandler {
private Object target;
private Map<String, Runnable> methodEnhancements;
public CustomLogicHandler(Object target) {
this.target = target;
this.methodEnhancements = new HashMap<>();
methodEnhancements.put("drive", () -> System.out.println("开车增强"));
methodEnhancements.put("off", () -> System.out.println("下车增强"));
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 根据方法名获取增强逻辑
Runnable enhancement = methodEnhancements.get(method.getName());
if (enhancement != null) {
enhancement.run();
}
// 委托给目标对象执行原方法
Object result = method.invoke(target, args);
return result;
}
}
Fute实现类(待增强类)
class FuTe implements Cat {
@Override
public void drive() {
System.out.println("我要开始开车了");
}
@Override
public void off() {
System.out.println("我要下车了");
}
public static void main(String[] args) {
Cat realObject = new FuTe();
CustomLogicHandler customLogicHandler = new CustomLogicHandler(realObject);
Cat proxyObject = (Cat) new $Proxy0(customLogicHandler);
proxyObject.drive();
System.out.println("------");
proxyObject.off();
}
}
总结:在这个例子中,CustomLogicHandler中的methodEnhancements存储了不同方法的增强逻辑,而不再使用if语句。在$Proxy0中的methods也类似地存储了不同方法的Method对象。这种方式可以更灵活地处理不同方法的增强逻辑,而不需要使用大量的if语句。
通过JDK动态代理类实现一个类中多种方法的不同增强的更多相关文章
- SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架
1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...
- Java基础-JDK动态代理
JDK的动态代理依靠接口实现 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...
- 【原创】JDK动态代理,此次之后,永生难忘。
动态代理,这个词在Java的世界里面经常被提起,尤其是对于部分(这里强调“部分”二字,因为有做了一两年就成大神的,实力强的令人发指,这类人无疑是非常懂动态代理这点小伎俩的)做了一两年新人来说,总是摸不 ...
- Spring AOP高级——源码实现(3)AopProxy代理对象之JDK动态代理的创建过程
spring-aop-4.3.7.RELEASE 在<Spring AOP高级——源码实现(1)动态代理技术>中介绍了两种动态代理技术,当然在Spring AOP中代理对象的生成也是运用 ...
- 有点深度的聊聊JDK动态代理
在接触SpringAOP的时候,大家一定会被这神奇的功能所折服,想知道其中的奥秘,底层到底是如何实现的.于是,大家会通过搜索引擎,知道了一个陌生的名词:动态代理,慢慢的又知道了动态代理有多种实现方式, ...
- JDK动态代理浅析
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2018-06-29/17.html 作者:夜月归途 出处:http://www.guitu ...
- jdk 动态代理的原理
一.代理设计模式 代理设计模式是Java常用的设计模式之一. 特点: 01.委托类和代理类有共同的接口或者父类: 02.代理类负责为委托类处理消息,并将消息转发给委托类: 03.委托类和代理类对象通常 ...
- (转)细说JDK动态代理的实现原理
原文:http://blog.csdn.net/mhmyqn/article/details/48474815 关于JDK的动态代理,最为人熟知的可能要数Spring AOP的实现,默认情况下,Spr ...
- JDK动态代理代码示例
JDK动态代理代码示例 业务接口 实现了业务接口的业务类 实现了InvocationHandler接口的handler代理类 1.业务接口 package com.wzq.demo01; /** * ...
- jdk动态代理使用及原理
jdk动态代理的使用 1.创建实现InvocationHandler接口的类,实现invoke(Object proxy, Method method, Object[] args)接口,其中invo ...
随机推荐
- SpringBoot2.7升级到3.0的实践分享
背景 最近把项目中的技术框架做一次升级,最重要的就是SpringBoot从2.7.x升级到3.0.x,当然还会有一些周边的框架也会连带着升级,比如Mybatis Plus,SpringCloud等,话 ...
- 垃圾000000000000000000000写了很多,保存不上,发送失败了。。。。。A
垃圾000000000000000000000写了很多,保存不上,发送失败了.....A垃圾000000000000000000000写了很多,保存不上,发送失败了.....A垃圾0000000000 ...
- Face to Face with Hurricane Camille
1.Face to Face with Hurricane Camille Joseph P. Blank 1 John Koshak, Jr., knew that Hurricane Camill ...
- 唱衰这么多年,PHP 仍然还是你大爷!
PHP 是个庞然大物. 尽管有人不断宣称 PHP "即将消亡". 但无法改变的事实是:互联网依然大量依赖 PHP.本文将通过大量的数据和事实告诉你为何 PHP 仍然在统治着互联网, ...
- 手撕Vuex-Vuex实现原理分析
本章节主要围绕着手撕 Vuex,那么在手撕之前,先来回顾一下 Vuex 的基本使用. 创建一个 Vuex 项目,我这里采用 vue-cli 创建一个项目,然后安装 Vuex. vue create v ...
- P9481 [NOI2023] 贸易 题解
题目链接 题目要求我们求出任意两点间最短路径之和,由于图比较特殊,除树边外只有祖先到其子树内的边,我们首先考虑最短路径有没有什么特殊性质. 注意到两点之间的最短路分为一下三种: 节点到其祖先的最短路: ...
- 使用Github Copilot生成单元测试并执行
上一篇文章我们介绍了 使用Github Copilot完成代码编写 本文我们继续使用Github Copilot在已有代码的基础上生成代码测试并执行. 一.先说一下代码的背景 需要上需要提供一个度量衡 ...
- 如何使用Python将PDF转为Excel
PDF文件是一种静态文档格式,通常难以编辑,而Excel则是一个灵活的表格工具.如果你需要处理PDF表格中的数据,那么将其导出为Excel文件可以大大节省工作时间和精力.Excel提供的强大数据编辑和 ...
- ZooKeeper论文阅读笔记
ZooKeeper论文传送门 介绍 ZooKeeper 是一个开源的分布式协调服务,它提供了高可用性和一致性的数据管理和协调功能.它被设计用于构建可靠的分布式系统,并提供了一组简单而强大的 wait- ...
- Docker 安装教程
一.离线安装 一.CentOS 离线安装 一.下载地址 1.选择系统的型号,选择linux-CentOS 下载地址 2.上传文件到CentOS 服务器 #选择文件 rz 二.开始安装 1.解压压缩包 ...