静态代理,jdk动态代理以及Cglib区别

【Spring Cloud】OpenFeign与全局异常处理 原理基于请求头传递错误消息,利用aop和全局异常拦截机制实现。 阅读详情

众所周知,Spring AOP中涉及到了动态代理模式,那么有动态代理相应的就会有静态代理。那么动态代理分为哪几种,相对应的区别又是什么呢?

首先什么是代理?

找一个东西或者一个人去帮你做事,比如常说的中介就是一个代理,各大经销商的代理商等等。JAVA中的代理即是指将自己的事情委派给别人帮忙去完成。

静态代理:代理的是程序员已经创建好的类,也就是说当前仅有一个对象能被成功代理。上代码看下

首先是一个需要代理的接口类

该类描述了两个方法,一个是eat(),一个是run();

public interface UserAction {
void eat();
void run();
}

接下来是该类的实现类,较为简单的实现方式,仅仅打印内容而已。

public class UserActionImpl implements UserAction {
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void run() {
System.out.println("跑步");
}
}

接口已经实现完成,剩下的即是代理对象了。上述的过程中静态代理和JDK的动态代理还没有区别。区别在于下面

public class UserActionStaticProxy implements UserAction{
private UserAction userAction;
public UserActionStaticProxy(UserAction userAction){
this.userAction = userAction;
}
@Override
public void eat() {
System.out.println("静态代理eat方法开始");
userAction.eat();
System.out.println("静态代理eat方法结束");
}
@Override
public void run() {
System.out.println("静态代理run方法开始");
userAction.run();
System.out.println("静态代理run方法结束");
}
}

从上述代码可以看到,我们实现了接口类并定义了一个新的类 UserActionStaticProxy 。然后定义了他的有参构造方法,将接口类传入即可。方法重写的同时加入了方法的监控。

public static void main(String[] args) {
UserAction userAction = new UserActionStaticProxy(new UserActionImpl());
userAction.eat();
}

在调用的时候,我们可以看到传入了UserActionImpl类去转换为UserAction类(向下转型),而后可以直接调用他的方法即可。运行上述方法以后即执行了 Proxy 类下的eat方法。甚至于我们可以在 Proxy 类下的eat方法调用一次 this.run() 方法,可以自己拼接为自己所想要的方式,有点和策略模式靠近了。(下图是在eat方法中加入了this.run()方法)

 

从静态代理模式中可以看出来,如果我们需要代理多个类的话,那么就需要新建对应的接口实现类(Imp.class)和对应的代理类(Proxy,class)。所以实现起来会比较繁琐,因此就应运而生出了动态代理。

动态代理和静态代理的本质区别其实不是很大,都需要接口以及接口的实现类,动态代理解决了需要重复新增大量的单体代理文件,而是把所有的对象都在一个地方进行了代理,也就是涉及到了JAVA中的反射机制。

可以看下动态代理的代码:

public class LogHandler implements InvocationHandler {
private Object object;
public Object newProxyInstance(Object object){
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
System.out.println("动态代理" + method.getName() + "开始");
Object ret = method.invoke(object,args);
System.out.println("动态代理" + method.getName() + "结束");
return ret;
}
}

可以看到,动态代理的时候,我们将对象替换成了所有对象的父类------Object类,在代理类的同时,我们通过反射Proxy.newProxyInstance 获取了该类的对象。而后使用了java对应的invoke方法去执行被代理类的方法。

对应的执行的主方法:

public static void main(String[] args) {
UserAction userAction1 = (UserAction)new LogHandler().newProxyInstance(new UserActionImpl());
userAction1.eat();
}

执行的结果:

 

因此可以看到,静态代理和动态代理的区在于代理类的区别,静态代理在代码扩容时,每增加一个接口类需要代理,那么就需要新增一个对应的代理类。而动态代理的好处在于需要新增代理接口时,不需要新增代理类,可以直接通过反射的方式调用被代理类。从上述就可以看出,代理的好处就是对方法的增强,可以在方法的前后进行一系列的操作,比如打印日志,验证权限,方法之后可以统一返回格式,统一异常捕获等等......(其实也就是AOP能做的事情)。所以动态代理相比于静态代理最本质的区别就在于我们需要对一个新的接口类代理时,不需要再去增加繁琐的代理类了。

前文提到,动态代理又分为JDK的动态代理以及CGLIB的动态代理。JDK的动态代理是依据的JAVA强大的反射机制。而CGLIB动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理,也就是说生成被代理类的一个子类将其方法覆盖,以达到代理的目的。

AOP是会自动切换这两种动态代理的类型的,具体的区别如下:

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

这里借用别人的CGLIB代码来看下具体的区别

public class UserAction {
public void eat(){
System.out.println("CGLIB动态代理吃饭");
}
}
public class CglibProxy implements MethodInterceptor {
private Object target;//需要代理的目标对象
//重写拦截方法
@Override
public Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {
System.out.println("Cglib动态代理,监听开始!");
Object invoke = method.invoke(target, arr);//方法执行,参数:target 目标对象 arr参数数组
System.out.println("Cglib动态代理,监听结束!");
return invoke;
}
//定义获取代理对象方法
public Object getCglibProxy(Object objectTarget){
//为目标对象target赋值

this.target = objectTarget;
Enhancer enhancer = new Enhancer();
//设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类

enhancer.setSuperclass(objectTarget.getClass());
enhancer.setCallback(this);// 设置回调

Object result = enhancer.create();//创建并返回代理对象

return result;
}
public static void main(String[] args) {
CglibProxy cglib = new CglibProxy();//实例化CglibProxy对象

UserAction user =  (UserAction) cglib.getCglibProxy(new UserAction());//获取代理对象

user.eat();//执行方法


}
}

代码本质上其实和JDK的动态代理的区别并不是很大,而JDK的动态代理是基于接口的,必须要对应接口的实现类才可以实现JDK的动态代理,而CGLIB弥补了这方面的缺点,CGLIB是基于类的继承关系,因此在没有接口的实现下我们可以使用CGLIB去实现动态代理。

推荐阅读

为什么阿里巴巴的程序员成长速度这么快?

纳尼?SpringCloud要被淘汰了?

《飞马计划》到底是什么? 可以让数万程序员为之着迷

一年半开发经验拿多少钱合适?

看完三件事

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

关注公众号 『 Java斗帝 』,不定期分享原创知识。

同时可以期待后续文章ing🚀

AOP进阶实战——双切面实现集中打印Feign日志 文章目录 1、背景 2、单切:记录Controller日志 2.1、切入点配置 2.2、方法执行前 2.3、方法执行后 2.4、方法执行异常时 3、双切:记录Feign日志 3.1、切入点配置 3.2、在调用FeignClient接口前 3.3、在调用LoadBalancerFeignClient中的execute方法前 3.4、在FeignClient接口响应完成后 3.5、在LoadBalancerFeignClient中的execute方法抛出异常 4、异步记录数据库 5、业务失败不回滚 附录一:切入 阅读详情

相关推荐

【RF】Receiver Function接收函数:从理论到实践的深度解析

本文深入解析地震学中的接收函数(Receiver Function, RF)技术,从理论原理到实践操作。文章将RF比作地球的“听诊器”,详细阐述了其通过反褶积剥离震源影响、揭示地下结构(如莫霍面)的核心机制,并提供了使用Python和rf库进行数据处理、计算、动校正与叠加的完整实战流程,同时探讨了其应用、局限性与常见问题的解决方案。

Jerry的专栏 121

Java 代理模式详解,静态代理与动态代理的区别及优缺点

代理模式(Proxy Pattern)是指通过代理对象控制对目标对象的访问,并在不改变目标对象的情况下添加额外的功能或控制访问。代理对象和目标对象实现相同的接口,使得客户端可以通过代理对象间接地访问目标对象。代理模式属于结构型设计模式,它在系统中引入了一个代理对象,该对象代替了客户端直接访问目标对象,从而可以在目标对象的基础上增加一些额外的功能或控制访问。

m0_71777195的博客 2796

避坑指南:麒麟系统ARM架构下PostGIS离线安装常见问题解析

本文深度解析了在国产麒麟系统ARM64架构下进行PostGIS离线安装的完整路径与核心避坑点。通过对比Docker容器化与源码编译两种部署方式的优劣,详细阐述了离线Docker环境搭建、ARM64镜像获取验证、容器化配置及常见故障排查的全流程,为在特殊环境下稳定部署空间数据库提供了一套可靠的实践指南。

Python的专栏 287

JAVA静态代理和动态代理理解

代理 代理是英文 Proxy 翻译过来的。我们在生活中见到过的代理,大概最常见的就是朋友圈中卖面膜的同学了。 她们从厂家拿货,然后在朋友圈中宣传,然后卖给熟人。 这里写图片描述 按理说,顾客可以直接从厂家购买产品,但是现实生活中,很少有这样的销售模式。一般都是厂家委托给代理商进行销售,顾客跟代理商打交道,而不直接与产品实际生产者进行关联。 所以,代理就有一种中间人的味道。 接下来,我们说说软件中的代理模式。 代理模式 代理模式是面向对象编程中比较常见的设计模式。 这里写图片描述 这是常见代理模式常见的

黄小龙的博客 790

中国裁判文书网案例批量爬取

本文介绍了某法院网站数据采集的技术研究过程,主要包含JS逆向分析和数据解密方法。通过开发者工具分析发现页面数据经过加密处理,重点研究了ciphertext等加密参数的生成逻辑。文章详细记录了定位加密函数、扣取加密代码、解密数据处理的全流程,并验证了解密方法的有效性。研究过程中强调了技术使用的法律边界,明确声明仅用于合法技术研究,禁止任何非法数据爬取行为。最终实现了加密数据的成功解密,并解释了各请求参数的作用,为后续数据清洗和存储奠定了基础。

2303_80825459的博客 816

大模型微调框架之TRL

近年来,大语言模型(LLMs)的快速发展推动了下游应用的繁荣,但如何高效地对这些模型进行对齐和微调,依然是研究与应用的热点。Hugging Face 开源的 TRL(Transformer Reinforcement Learning) 框架,提供了基于强化学习的语言模型训练方法,并支持 SFT(监督微调)、PPO(近端策略优化)、DPO(直接偏好优化)等多种方式,是目前对齐和微调 LLM 的重要工具。

和大家一起涨芝士 904

什么是静态代理和动态代理,两者的区别(笔记)

文章目录1.什么是代理?2.静态代理3.动态代理4.总结: 1.什么是代理? ​ 代理: 就是让代理角色帮助真实角色完成一件事情; ​ 举例:过年回家让朋友代买火车票,朋友帮你买火车票的过程就是代理 2.静态代理 ​ 什么是静态代理: 静态代理相当于是多写了一个代理类,在调用的时候调用的是代理类,在代理类中的处理还是原生的处理逻辑,不过在前后添加上需要添加的代码。 缺点:需要为每一个被代理的对象都创建一个代理类。 ​ 特点: ​ 代理角色和真实角色都需要实现同一个接口, ​ 真实角色专注于自己的.

m0_67499084的博客 6001

分布式推理服务(策略:数据并行、张量并行、流水线并行、专家并行)技术分析

摘要:分布式推理突破单GPU内存和算力限制,支持大模型部署。四种核心策略包括: 数据并行:复制模型拆分数据,提升吞吐但内存效率低; 流水线并行:模型分阶段执行,支持超大模型但存在计算气泡; 张量并行:拆分层内矩阵运算,延迟低但通信开销大; 专家并行:动态激活MoE模型专家,计算高效但路由复杂。实际应用中常组合策略(如3D并行),需权衡模型规模、硬件条件与性能目标。

技术引领业务创新 943

静态代理、JDK动态代理、CGLIB动态代理以及JDK和CGLIB动态代理的区别

代理模式在 Java 开发中是一种比较常见的设计模式。设计目的旨在为服务类与客户类之间插入其他功能,插入的功能对于调用者是透明的,起到伪装控制的作用。如租房的例子: 房客、中介、房东。对应于代理模式中即:客户类、代理类 、委托类 (被代理类)为某一个对象(委托类)提供一个代理 (代理类),用来控制对这个对象的访问。委托类和代理类有个共同的父类或父接口。代理类会对请求做预处理、过滤,将请求分配给指定对象。//目标对象//通过构造器传入目标对象/*** 获取代理对象* @return*/

来都来了 1139

UE4打包为Framework库嵌入iOS原生工程

UE4打包为Framework库嵌入iOS原生工程

tangfuling1991的博客 1294

ITKMontage---ITK自动拼接模块

本文分享ITK中Remote中的ITKMontage拼接模块,希望对各位小伙伴有所帮助!1. ITKMontage介绍在医疗图像处理过程中,图像拼接有很多用处,比如DR图像的拼接。ITKMontage可以快速稳定的处理数据量较大的拼接图像。强度不均匀性校正配准全局优化融合2. ITKMontage安装ITKMontageITKMontage可脱离ITK进行单独安装,也可在ITK安装时作为模块进行安装。单独安装ITK模块安装在ITK编译时,选择ITKMontage模块。

qq_40041064的博客 450

JDK静态代理、JDK动态代理、Cglib动态代理区别

一、代理模式介绍 什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被代理的人能干活呀。说白了经纪人懂吧,整不好就绿你的那种。 二、JDK静态代理 场景:比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理呀,然后就绿了大郎。。。 第一步:定义一种类...

Coding Farmer的博客 1481

养龙虾之_因特尔UHD/ULtra/Arc核显跑大模型_安装ollama_跑qwen3.5:0.8b/9b_使用copaw1.0.1测试_并配置copaw技能效果炸裂---AI大模型应用探索0019

摘要:本文探讨了利用Intel UHD770核显运行大语言模型的可能性。通过使用Intel发布的ipex-llm项目工具包,成功在核显上运行了Qwen3.5系列模型。测试发现0.8B小模型运行流畅(3-5秒响应),但智能程度有限;而9B大模型虽然效果更好,但响应时间长达2分钟,且GPU/CPU占用率不高。实验证明Intel核显确实可以运行LLM,但实际效果和性能表现仍有提升空间,特别是对大模型的支持尚不理想。

添柴程序猿的专栏 232

【什么是静态代理?什么是动态代理?JDK动态代理和CGLIB包实现动态代理的区别】

【什么是静态代理?什么是动态代理?JDK动态代理和CGLIB包实现动态代理的区别】JVM层面:在编译时就已经实现,编译完成后代理类是一个实际的class文件。灵活性:静态代理中,接口一旦新增加方法,目标对象和代理对象都要进行修改,非常麻烦的。使用JDK静态代理很容易就完成了对一个类的代理操作。但是JDK静态代理只能为一个类服务,如果需要代理的类很多,那么就需要编写大量的代理类,比较麻烦。JVM层面:在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中。

Coder_ljw的博客 550

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

代理模式详解:静态代理+JDK CGLIB 动态代理实战(动态代理和静态代理的区别 JDK动态代理 和 CGLIB 动态代理的区别)

文章目录1. 代理模式2. 静态代理3. 动态代理3.1. JDK 动态代理机制3.1.1. 介绍3.1.2. JDK 动态代理类使用步骤3.1.3. 代码示例3.2. CGLIB 动态代理机制3.2.1. 介绍3.2.2. CGLIB 动态代理类使用步骤3.2.3. 代码示例3.3. JDK 动态代理和 CGLIB 动态代理对比4. 静态代理和动态代理的对比5. 总结 1. 代理模式 代理模式是一种比较好的理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样

Aladdin_Lamp的博客 809

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

静态代理、JDK和CGLIB动态代理区别

一、 JDK和CGLIB动态代理 1、JDK动态代理 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。 2、CGLIB动态代理 利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。 3、何时使用JDK还是CGLIB? 1)如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。 2)如果目标对象实现了接口,可以强制使用CGLIB实现AOP。 3)如果目

jike11231的博客 815

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

静态代理和动态代理的区别,JDK动态代理和CGLIB动态代理的区别

代理对象是自己手动创建的,只能代理一种角色。可以根据真实角色自动生成对应类型的代理对象。

qq_64847107的博客 286

cglib和jdk动态代理区别_java静态代理与动态代理

1. 静态代理与动态代理区别静态代理:需要编写批量代理类动态代理:不需要编写批量代理类2.静态代理静态代理结构如下:编写测试接口:public interface TestInteface { /** * 测试方法 */ String runNow(String param);}//end编写测试类:public class TestProxy implements TestInteface { ...

weixin_39792803的博客 83

Java静态代理,jdk动态代理,cglib动态代理的区别

Java静态代理和动态代理 1.代理模式 给某一个对象提供一个代理,并由代理对象来控制对真实对象的访问。代理模式是一种结构型设计模式。 代理模式角色分为 3 种: 抽象角色:一般是一个接口或者抽象类,定义了一些公共方法; 真实角色:真正实现业务逻辑的类,也是被代理的角色; 代理角色:用来代理和封装真实主题 真实角色和代理角色必须实现同一个抽象角色的接口。 2.静态代理 所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和真实主题角色的关系在运行前就确定了。 2.1 lol代练解释静态代理 以一个

weixin_32629733的博客 447

【Spring AOP】【AspectJ】【CGLIB】【JDK动态代理】【JDK静态代理】区别

今天复习了一下AOP相关概念。 有这么几个知识名词需要好好理解一下。 基本上可以概括为动态和静态两类 【动态】CGLIB、JDK动态代理、Spring AOP 【静态】AspectJ、JDK静态代理

知至智 4510

Java 静态代理、JDK动态代理、CGLIB代理的区别及原理

Java 静态代理、JDK动态代理、CGLIB代理 代理(Proxy):是一种设计模式,提供了对目标对象另外的访问方式,即通过代理对象访问目标对象。 好处:可以在目标对象实现的基础上,增强额外的功能操作,即目标对象的扩展功能。 举个例子:假如产品经理提了一个新的需求,需要在某个方法调用之前以及调用之后打印日志。那么我们就可以通过代理的方式,不修改方法内部的代码而实现。 1. Java静态代理 静态代理: 代理对象和目标对象实现相同的接口或者继承相同的父类,然后通过调用代理对象的方法来调用目标对象的方法实现代

Code-CHAN的博客 589

【Java基础】代理模式、静态代理、动态代理、JDK与CGLIB代理区别、在spring AOP中的应用

目录 代理模式 静态代理和动态代理 静态代理 动态代理 JDK动态代理 CGLIB动态代理 动态代理在Spring AOP中的应用场景 本人运行环境为JDK8,CGLIB版本为3.1。 在某些情况下,客户不想或者不能直接引用另一个对象,这时候可以创建一个目标对象的代理对象,在客户端和目标对象之间起到中介的作用。“代理”即为目标对象提供一种代理以控制对这个对象的访问。 代理模式 如果你学过设计模式,你应该会知道“代理模式”,即在不用修改原类代码的前提下对原类的一些方法进行功能增强,比如s

奋进的小白粥 435

java面试题,什么是动态代理?、动态代理和静态代理有什么区别?说一下反射机制?JDK Proxy 和 CGLib 有什么区别?动态代理的底层

java面试题,什么是动态代理?、动态代理和静态代理有什么区别?说一下反射机制?JDK Proxy 和 CGLib 有什么区别?动态代理的底层

hutao8896的博客 1356

静态代理和JDK、Cglib动态代理区别

代理模式:由被代理对象(业务类)和代理类组成,代理类通常包括日志代理类、权限代理类。 代理源代码分析,转载此篇博客: https://blog.youkuaiyun.com/fanrenxiang/article/details/81939357 静态代理 被代理对象和代理类都确定时可以采用静态代理。 静态代理有两种方式继承和聚合, 聚合较为常用。 动态代理 被代理对象多,代理类多的情...

摸金校尉的博客 572
上一篇: 巧合?达摩院2021十大科技是十九世纪那场幻想的升级版?
下一篇: Java微服务 vs Go微服务,究竟谁更强!?
Java斗帝之路
博客等级 码龄7年 2392粉丝 687原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值