代理模式———静态代理、动态代理(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

相关文章

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL