当前位置: 首页 > news >正文

Java面试八股之JDK 动态代理和 CGLIB 动态代理的区别

  1. JDK 动态代理和 CGLIB 动态代理的区别

JDK 动态代理和 CGLIB 动态代理都是在 Java 中实现动态代理的两种常见方式。它们各自有不同的特点和适用场景。下面详细介绍一下这两种动态代理的区别:

1. 代理机制

JDK 动态代理:

实现原理: JDK 动态代理基于 Java 的反射机制,通过反射创建一个代理对象,该代理对象实现与目标对象相同的接口。

接口要求: 要求被代理的对象必须实现至少一个接口。

应用场景: 适用于那些基于接口定义的行为代理。

CGLIB 动态代理:

实现原理: CGLIB 是一个高性能的代码生成库,它使用字节码技术生成代理类。CGLIB 创建的代理类不是目标类的子类,而是通过继承一个代理类来实现代理功能。

接口要求: 不要求被代理的对象实现接口,可以代理任何类。

应用场景: 适用于那些没有提供接口的目标对象,或者需要代理所有方法(包括 final 方法)的场景。

2. 代理对象

JDK 动态代理:

生成的代理对象是目标对象所实现接口的实现类。

代理对象可以调用目标对象未实现的方法。

CGLIB 动态代理:

生成的代理对象是目标对象的子类。

代理对象不能调用目标对象的 final 和 private 方法,因为这些方法在子类中不可见。

3. 生成代理对象的方式

JDK 动态代理:

使用 java.lang.reflect.Proxy 类来创建代理对象。

通过调用 Proxy.newProxyInstance() 方法并传入以下参数:

加载类的 ClassLoader。

目标对象实现的接口数组。

InvocationHandler 对象,用于处理代理对象的方法调用。

CGLIB 动态代理:

使用 net.sf.cglib.proxy.Enhancer 类来创建代理对象。

通过调用 Enhancer.create() 方法并设置代理增强器(Enhancer)的相关属性,如设置代理对象的目标对象、回调方法等。

4. 性能比较

JDK 动态代理:

性能较好,因为它是基于 Java 语言级别的,不涉及字节码操作。

但是,如果目标对象实现了多个接口,则每次生成代理类时都需要创建新的代理类,这可能会导致类加载开销。

CGLIB 动态代理:

性能在大多数情况下略逊于 JDK 动态代理,因为涉及到字节码的生成和类加载。

但是,由于 CGLIB 可以代理任何类,所以在某些情况下它是唯一的选择。

5. 使用场景

JDK 动态代理:

当目标对象实现了接口时,首选 JDK 动态代理。

适用于需要对多个实现相同接口的目标对象进行相同行为增强的场景。

CGLIB 动态代理:

当目标对象没有实现接口时,或者需要代理所有方法时,可以选择 CGLIB 动态代理。

适用于需要对单个目标对象进行行为增强的场景。

如果大家需要视频版本的讲解,欢迎关注我的B站:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 用户画像系列——Spark任务调优实践
  • mysql问题解决
  • 【Material-UI】Icon Button 组件详解
  • 【2.4 python中的基本输入和输出】
  • 【vulnhub】Bob:1.0.1靶机
  • Redis入门概述
  • vulnhub之serial
  • 工作中,如何有效解决“冲突”?不回避,不退让才是最佳方式
  • 盘点Hutool6.0中新增的那些方法(上)
  • Day6
  • 缓冲流练习
  • js第二天
  • 最强开源文生图模型一夜易主!SD一作、Stabililty AI核心成员Robin Rombach下场创业了,一出手就是王炸。
  • Python 爬虫项目实战(一):爬取某云热歌榜歌曲
  • E23.【C语言】练习:不创建第三个变量实现两个整数的交换
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【译】理解JavaScript:new 关键字
  • 230. Kth Smallest Element in a BST
  • Android 架构优化~MVP 架构改造
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • MYSQL 的 IF 函数
  • node 版本过低
  • PHP面试之三:MySQL数据库
  • Python - 闭包Closure
  • Rancher-k8s加速安装文档
  • windows下如何用phpstorm同步测试服务器
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 聚簇索引和非聚簇索引
  • 深度学习中的信息论知识详解
  • 使用common-codec进行md5加密
  • 我的zsh配置, 2019最新方案
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • # 透过事物看本质的能力怎么培养?
  • ## 基础知识
  • #{} 和 ${}区别
  • #pragma once与条件编译
  • $nextTick的使用场景介绍
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (多级缓存)缓存同步
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)关于pipe()的详细解析
  • (转载)(官方)UE4--图像编程----着色器开发
  • .net core + vue 搭建前后端分离的框架
  • .net 发送邮件
  • .NET 服务 ServiceController
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .Net的C#语言取月份数值对应的MonthName值
  • .net网站发布-允许更新此预编译站点
  • /*在DataTable中更新、删除数据*/
  • @PostConstruct 注解的方法用于资源的初始化
  • @RequestParam,@RequestBody和@PathVariable 区别
  • @Transaction注解失效的几种场景(附有示例代码)
  • @WebService和@WebMethod注解的用法