final类又没实现接口应该用哪一种代理, jdk动态代理还是cglib代理
jdk动态代理还是cglib代理🧙
- jdk动态代理和cglib代理的示例
- JDK动态代理原理
- CGLIB代理
- final类又没实现接口应该用哪一种代理, jdk动态代理还是cglib代理
滚滚长江东逝水,浪花淘尽英雄。——唐代杨炯《临江仙》
jdk动态代理和cglib代理的示例
以下是一个使用JDK动态代理和CGLIB代理的示例。我们首先创建一个接口和实现类,然后分别使用JDK动态代理和CGLIB代理来创建代理对象。
- 接口:
UserService.java
public interface UserService {void addUser(String name);
}
- 实现类:
UserServiceImpl.java
public class UserServiceImpl implements UserService {@Overridepublic void addUser(String name) {System.out.println("Adding user: " + name);}
}
- JDK动态代理:
JdkProxyHandler.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JdkProxyHandler implements InvocationHandler {private Object target;public JdkProxyHandler(Object target) {this.target = target;}@SuppressWarnings("unchecked")public <T> T getProxyInstance() {return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("JDK Proxy - Before method execution");Object result = method.invoke(target, args);System.out.println("JDK Proxy - After method execution");return result;}
}
- CGLIB代理:
CglibProxyHandler.java
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CglibProxyHandler implements MethodInterceptor {private Object target;public CglibProxyHandler(Object target) {this.target = target;}@SuppressWarnings("unchecked")public <T> T getProxyInstance() {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return (T) enhancer.create();}@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("CGLIB Proxy - Before method execution");Object result = proxy.invokeSuper(obj, args);System.out.println("CGLIB Proxy - After method execution");return result;}
}
- 测试类:
ProxyTest.java
public class ProxyTest {public static void main(String[] args) {UserService userService = new UserServiceImpl();// 使用JDK动态代理JdkProxyHandler jdkProxyHandler = new JdkProxyHandler(userService);UserService jdkProxy = jdkProxyHandler.getProxyInstance();jdkProxy.addUser("John");System.out.println("------------------------------------");// 使用CGLIB代理CglibProxyHandler cglibProxyHandler = new CglibProxyHandler(userService);UserService cglibProxy = cglibProxyHandler.getProxyInstance();cglibProxy.addUser("Jane");}
}
运行 ProxyTest.java,你将看到以下输出:
JDK Proxy - Before method execution
Adding user: John
JDK Proxy - After method execution
------------------------------------
CGLIB Proxy - Before method execution
Adding user: Jane
CGLIB Proxy - After method execution
JDK动态代理和CGLIB代理都是AOP(面向切面编程)中的实现技术,它们可以在不修改目标类代码的情况下,为目标类添加一些额外的功能。
JDK动态代理原理
JDK动态代理是基于Java反射机制实现的。它主要使用了java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
JDK动态代理的核心思想是:为目标类创建一个代理对象,这个代理对象实现了目标类的接口。当代理对象的方法被调用时,实际上是调用了InvocationHandler的invoke方法。在invoke方法中,我们可以在调用目标类方法之前和之后执行一些自定义的逻辑。
要使用JDK动态代理,需要满足以下条件:
- 目标类必须实现一个或多个接口。
- 为目标类编写一个
InvocationHandler实现类。
JDK动态代理的主要局限在于它只能代理实现了接口的类。如果一个类没有实现接口,就无法使用JDK动态代理。
CGLIB代理
CGLIB(Code Generation Library)是一个第三方代码生成库,它可以在运行时为目标类生成一个子类。CGLIB代理的核心思想是:为目标类创建一个子类,并覆盖目标类的方法。当代理类的方法被调用时,实际上是调用了MethodInterceptor的intercept方法。在intercept方法中,我们可以在调用父类(即目标类)方法之前和之后执行一些自定义的逻辑。
要使用CGLIB代理,需要满足以下条件:
- 目标类不能是final的,因为CGLIB需要生成目标类的子类。
- 为目标类编写一个
MethodInterceptor实现类。
CGLIB代理的优势在于它不要求目标类实现接口,但是由于它是通过创建子类来实现代理的,所以目标类不能是final的。
JDK动态代理基于Java反射机制,要求目标类实现接口。它创建的代理对象实现了目标类的接口,并通过
InvocationHandler来实现方法拦截。
CGLIB代理基于代码生成技术,不要求目标类实现接口。它创建的代理对象是目标类的子类,并通过
MethodInterceptor来实现方法拦截。
两者都可以实现在不修改目标类代码的情况下,为目标类添加额外功能。选择哪种代理方式取决于目标类是否实现了接口以及其他特殊需求。
final类又没实现接口应该用哪一种代理, jdk动态代理还是cglib代理
如果目标类是final类且没有实现接口,那么JDK动态代理和CGLIB代理都无法直接对其进行代理。JDK动态代理要求目标类实现一个或多个接口,而CGLIB代理需要生成目标类的子类,对于final类是无法创建子类的。
在这种情况下,你可以考虑以下解决方案:
-
修改目标类,去除
final修饰符,或为其实现一个接口。然后,你可以选择使用JDK动态代理或CGLIB代理。 -
如果不能修改目标类,你可以尝试使用装饰器模式。创建一个新类,实现与目标类相同的接口(或扩展自目标类,如果目标类不是final的),并在新类中包装目标类。然后,在新类中实现代理逻辑。这种方式虽然不能直接代理目标类,但仍然可以在不修改目标类的情况下,为其添加额外的功能。
请注意,装饰器模式并非代理模式,但在某些情况下,它可以作为一种替代方案来实现类似的功能。
相关文章:
final类又没实现接口应该用哪一种代理, jdk动态代理还是cglib代理
jdk动态代理还是cglib代理🧙jdk动态代理和cglib代理的示例JDK动态代理原理CGLIB代理final类又没实现接口应该用哪一种代理, jdk动态代理还是cglib代理滚滚长江东逝水,浪花淘尽英雄。——唐代杨炯《临江仙》 jdk动态代理和cglib代理的示例 以下是一个使用…...
使用StaMPS_Visualizer
0 前言 StaMPS-Visualizer :由thho开发的用于可视化由StaMPS / MTI处理的DInSAR结果。 github地址:StaMPS-Visualizer 使用StaMPS_Visualizer需要配置好StaMPS,并安装好R和Rstudio Ubuntu中安装StaMPS StaMPS-Visualizer 安装步骤–在linux…...
高并发-高性能-高可用-结论版
文章目录上万的并发需要多少台web服务器一般单机能处理200请求,为何redis单机却能处理上万请求单线程每秒能处理(发送/响应)的http请求数三高的定义高并发的解决方案高性能的解决方案高可用的解决方案参考文章上万的并发需要多少台web服务器 …...
数智转型助力建筑业全产业链升级,你了解多少?
关于数智转型,指的是基于数字化技术和数据驱动的思维方式,将企业的管理、业务和服务进行全面的升级和改造,从而帮助实现企业的数字化转型和升级。通过数字技术和数据分析来提高企业的效率、创新能力和竞争力,进一步提高企业的市场…...
Python网络设备脚本中经常使用的connecthandler和telnetlib是什么意思?
你好,这里是网络技术联盟站。 在昨天的文章中,有小伙伴提到对这两天瑞哥提供的Python脚本中涉及的connecthandler和telnetlib两个模块不是太了解,想要学习一下: 今天瑞哥就安排上! 其实这两个模块是Python与网络设备…...
你真的会写 git commit message 吗?
作者:明明如月学长, CSDN 博客专家,蚂蚁集团高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《EffectiveJava》独家解析》专栏作者。 热门文章推荐…...
ISO文件内添加kickstart完成自动安装
目录 将待制作的centos iso文件挂载到/mnt/目录 将/mnt/下的所有文件复制到新的目录/tmp/mycentos 创建kickstart文件 修改启动文件 重新制作ISO文件 制作完成 kickstart可以实现根据配置自动安装操作系统,本文主要讲解如何让机器读取到iso文件后自动完成操作…...
SpringBoot 整合RabbitMq 自定义消息监听容器来实现消息批量处理
SpringBoot 整合RabbitMq 自定义消息监听容器来实现消息批量处理前言添加依赖配置文件编写监听器创建SimpleRabbitListenerContainerFactory发送消息前言 RabbitMQ是一种常用的消息队列,Spring Boot对其进行了深度的整合,可以快速地实现消息的发送和接收…...
jquery基础之操作节点对象
jquery操作节点(元素)对象 捕获-DOM操作,获取内容,值 获取内容:1.text()获取元素的文本内容 2.html()获取元素的文档内容 …...
对于Java的深入理解及其特点--面试
前言 计算机语言千千万,每一种语言都有其自己的特点、擅长的领域。在学习了Java之后才对Java有了进一步的理解。 面试问一: 你是如何理解Java这门语言的? 这里我们应该从下面几个点去总结 1、Java语言具有的属性 2、他的特点在哪 Java语…...
Linux GPSD的使用
目录 1: GPSD 运行状态查看 2:停止GPSD 服务 3: GPSD运行输出(协议的识别) 4:开启的服务...
ArrayList无参构造添加元素源码解读
一、ArrayList无参构造add方法源码阅读 Test//无参构造源码阅读 public void testArrayListNoConstructorAdd(){ArrayList<Integer> arrayList new ArrayList<>();ArrayList<Integer> list new ArrayList<>();arrayList.add(1);arrayList.add(12);a…...
手写简易 Spring(二)
文章目录手写简易 Spring(二)1. 扩展 BeanFactory 接口2. 实现资源加载器,从 Spring.xml 解析和注册 Bean 对象1. 核心实现类 XmlBeanDefinitionReader3. 实现应用上下文,自动识别、资源加载、扩展机制1. 应用上下文2. 核心实现类…...
排列问题DFS入门
1、题目描述(全排列) 输入一个正整数n,输出1~n的全排列。 输入格式 一个正整数n。 输出格式 所有1~n的全排列,每个排列占一行。 样例输入 3 样例输出 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 算法思路 题目要求输出n的全…...
【每日一题Day159】LC1638统计只差一个字符的子串数目 | 枚举
统计只差一个字符的子串数目【LC1638】 给你两个字符串 s 和 t ,请你找出 s 中的非空子串的数目,这些子串满足替换 一个不同字符 以后,是 t 串的子串。换言之,请你找到 s 和 t 串中 恰好 只有一个字符不同的子字符串对的数目。 比…...
【07 Metadata and VendorTag】
1. Metadata结构及分类 一个 metadata 通过tag,value及 type 来描述。不同的 metadata 分成三类 controls,dynamic 及 static 2. MTK Metadata IMetadata Mtk metadata containerIMetadataConverter Provide mutual conversion for Android camera_metadata and MTK Imetada…...
Golang中Model的使用
导语我们都知道在Golang中我们一般都是设置GOPATH目录,这个目录主要存放我们的第三方包,这个方式一直不是很方便,今天给大家介绍Go 1.11版本中推出的GoModul使用方法,学过java的同学,可能对maven包有所了解,…...
交友项目【基础环境搭建】
目录 1:交友项目架构介绍 1.1:前后端分离的概述 1.2:YAPI介绍(虚拟机中已经配好) 基本信息 使用 安装跨域拓展(浏览器上安装跨域处理插件) 2:虚拟机工具项目搭建 2.1࿱…...
入职时,公司要求自己带电脑,每月给100元补贴,如果不接受就不能入职!
为了节约成本,公司能做出什么事?一位网友遇到了这样的事:入职时,公司要求自己带电脑,每个月给100元补贴,如果不接受就得放弃入职,这样的公司有没有坑?有人问:连基本的公司…...
20道经典Redis面试题
20道经典Redis面试题 前言 整理了20道经典Redis面试题,希望对大家有帮助。 1. 什么是Redis?它主要用来什么的? Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用A…...
HBuilderX+Android Studio本地离线打包Uniapp安卓Apk全流程解析
1. 为什么需要本地离线打包? 每次用HBuilderX云打包都要排队等半天?项目紧急上线时看着进度条干着急?作为过来人,我太懂这种痛苦了。去年我们团队开发医疗问诊App时,高峰期云打包排队超过2小时,差点耽误版…...
芯片研发的残酷真相:流片成功只是开始
芯片成功"点亮"那一刻,项目算完成了吗?如果你认为算,那大概率还没经历过真正的芯片项目后期。事实是,点亮和demo跑通,只不过是拿到了入场券而已。真正的战斗,从客户拿到样片那一刻才开始。很多工…...
别再到处找转换工具了!用Audacity把WAV无损转成MP3,保姆级图文教程
音频处理新手指南:Audacity无损转换WAV到MP3的完整方案 你是否曾经下载了一段高质量录音,却发现文件体积大得惊人,根本无法通过邮件发送?或者尝试上传播客内容时,平台总是提示"文件格式不支持"?这…...
从单张图片到动态世界:Depth-Anything-3如何重塑3D视觉的通用法则
1. 当单张图片学会"思考"深度 第一次看到Depth-Anything-3(DA3)处理一张普通照片时,我盯着屏幕足足愣了三分钟。它就像给二维世界突然装上了Z轴——原本平淡无奇的街景照片,在DA3的解构下,近处的咖啡杯轮廓清…...
EdisonZhou
AI训练存储选型的演进路线 第一阶段:单机直连时代 早期的深度学习数据集较小,模型训练通常在单台服务器或单张GPU卡上完成。此时直接将数据存储在训练机器的本地NVMe SSD/HDD上。 其优势在于IO延迟最低,吞吐量极高,也就是“数据离…...
告别桌面混乱:NoFences让文件管理效率提升80%的空间收纳方案
告别桌面混乱:NoFences让文件管理效率提升80%的空间收纳方案 【免费下载链接】NoFences 🚧 Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 每天在杂乱的桌面图标中寻找文件,就像在堆…...
抖音批量下载工具:高效获取无水印视频与图文内容的全攻略
抖音批量下载工具:高效获取无水印视频与图文内容的全攻略 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…...
NVMe 2.0 Boot Partitions:解锁高效固件更新的双分区机制
1. 为什么我们需要NVMe 2.0的双启动分区? 想象一下你正在给手机升级系统,突然断电了——传统单分区方案会让设备直接变砖,而NVMe 2.0的双启动分区就像给系统上了双保险。这个设计最初是为了解决企业级SSD在724小时运行时的固件更新难题&#…...
先抛个干货:这个改进版的黑猩猩优化算法SLWChoA,新手照着敲就能跑,而且效果比原版和不少老算法都强
混合改进策略的黑猩猩优化算法SLWChoA:采用Sobel序列初始化种群,增强种群的多样性和随机性;引入凸透镜成像的反向学习策略,提高算法的收敛速度精度和速度;将水波动态自适应因子添加到攻击者位置更新出,增强…...
手把手教你用JavaScript实现国密SM4加密(附Node.js与微信小程序兼容代码)
从零构建JavaScript国密SM4加密引擎:跨平台实战指南 国密SM4算法作为我国商用密码体系的核心标准,正在金融、政务等领域加速替代国际加密算法。但对于JavaScript开发者而言,直接可用的SM4实现往往面临三大痛点:Node.js与微信小程序…...
