代理模式———静态代理、动态代理(JDK代理)、CGLIB代理

2024-09-06 09:58

本文主要是介绍代理模式———静态代理、动态代理(JDK代理)、CGLIB代理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、代理模式

代理模式就是为某个对象Q,提供一个代理对象,通过代理对象,完成对对象Q的引用。

通过代理对象的增强可以无侵入的扩展委托类。真正的业务实现还是交与委托类,代理类相当于包装了一层委托类,可以在委托类执行的前后加入扩展,比如缓存,切面,消息等。

在SpringAOP的实现中,使用的核心技术就是动态代理,使用了JDK代理(对象实现了接口使用)与CGLIB(对象没实现接口使用)代理的结合。

 

二、静态代理

 如上图所示,代理类和目标对象分别实现相同的接口。代理对象调用实现类,完成方法的调用和封装。

优点:

  • 可以做到不修改目标对象的情况下,对目标功能扩展

缺点:

  • 每个目标对象都需要一个代理类。
  • 接口每增加一个方法,都需要同时改动,代理类与目标对象。
  • (不用接口实现代理的是委托模式,直接用另一个对象包装,目标对象)

三、动态代理

动态代理也叫jdk代理,接口代理。

特点:

  • jdk 调用jdk,API接口,动态生成代理对象
  • 代理对象不需要实现接口

上代码

代理对象:                                                                                        调用:

JDK实现代理只需要使用newProxyInstance方法

这个方法需要三个参数:

  • ClassLoader loader,:定义代理类的类加载器
  • Class<?>[] interfaces,:代理类的实现接口集合
  • InvocationHandler h:调用方法时的调用处理器

根据这个newProxyInstance()方法会动态的创建出,代理对象

优点:

  •     代理类不需要实现接口
  •     相比静态代理,运行时生成代理对象,可在运行时指定代理的目标对象,和代理的逻辑。相比静态代理更加灵活,静态代理在编译期以及指定了,代理的目标对象和代理逻辑。
  •     可以任意指定目标对象,和代理逻辑。

缺点:

  • 目标对象需要实现对应的接口,没有接口的类,无法实现jdk动态代理。

四、CGLib代理

CGLib代理也叫做子类代理类。

CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。

特点:

  • 可以对无接口的类实现代理
  • 代理的类不能为final,否则报错
  • 目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.
public class CglibProxy implements MethodInterceptor {private Object target;//业务类对象,供代理方法中进行真正的业务方法调用//    //获得一个代理对象public Object getProxyInstance(Object target){this.target =target;//给业务对象赋值//1.工具类Enhancer en = new Enhancer();//创建加强器,用来创建动态代理类//2.设置父类en.setSuperclass(this.target.getClass());//为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦//3.设置回调函数en.setCallback(this);//4.创建子类(代理对象)return en.create();}@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("代理对象调用前处理");Object result =  methodProxy.invoke(o,args);//调用业务类(父类中)的方法System.out.println("代理对象调用后处理");return result;}
}
调用
  //3.cglib代理SubjectCGImpl target = new SubjectCGImpl();CglibProxy cglibProxy = new CglibProxy();SubjectCGImpl proxyInstance = (SubjectCGImpl)cglibProxy.getProxyInstance(target);proxyInstance.requ11est();

 这里调用的时候还会出现堆栈溢出的问题,目前还没找到原因。

CGLIB动态代理的性能比JDK动态代理的性能高10倍左右,但创建代理对象的速度却比JDK创建代理对象的速度慢15倍左右。对单利的代理对象创建使用CGLIB更合适。

 

这篇关于代理模式———静态代理、动态代理(JDK代理)、CGLIB代理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141704

相关文章

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M