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

Java动态代理详解

文章目录

  • 一、JDK动态代理
    • 1、关键类和接口
    • 2、实现步骤
  • 二、CGLIB动态代理
    • 1、关键类
    • 2、实现步骤
  • 三、总结

Java中的动态代理是一种设计模式,它允许在运行时创建代理对象,而不是在编译时。代理对象可以用来代理真实对象的方法调用。

Java中的动态代理主要有两种实现方式:JDK动态代理CGLIB动态代理

一、JDK动态代理

JDK动态代理使用Java标准库中的java.lang.reflect包来创建代理对象。它适用于实现了接口的类,通过接口类型来代理对象。

1、关键类和接口

  • InvocationHandler接口:
    这是一个接口,必须实现其invoke方法,代理对象的所有方法调用都会转发到这个方法。
  • Proxy类:
    这是一个用来创建代理对象的类,提供了静态方法newProxyInstance来生成代理对象。

2、实现步骤

1)定义接口和实现类:

public interface MyService {void perform();
}public class MyServiceImpl implements MyService {@Overridepublic void perform() {System.out.println("Executing perform method");}
}

2)实现InvocationHandler接口,编写代理逻辑

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method invoke");Object result = method.invoke(target, args);System.out.println("After method invoke");return result;}
}

3)使用Proxy.newProxyInstance方法创建代理对象

import java.lang.reflect.Proxy;public class Main {public static void main(String[] args) {MyService myService = new MyServiceImpl();MyInvocationHandler handler = new MyInvocationHandler(myService);MyService proxyInstance = (MyService) Proxy.newProxyInstance(myService.getClass().getClassLoader(),myService.getClass().getInterfaces(),handler);proxyInstance.perform();}
}

二、CGLIB动态代理

CGLIB(Code Generation Library)是一种强大的字节码生成库,它允许在运行时创建子类,适用于没有实现接口的类。CGLIB通过继承被代理类来创建代理对象,因此无法代理final类。

1、关键类

  • Enhancer类:
    这是CGLIB用来生成代理类的主要类,通过设置超类和回调来创建代理对象。
  • MethodInterceptor接口:
    这是一个接口,类似于InvocationHandler,需要实现intercept方法。

2、实现步骤

1)添加CGLIB依赖:

在项目中添加CGLIB库的依赖。对于Maven项目:

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>

2)定义实现类:定义一个没有实现接口的类

public class MyService {public void perform() {System.out.println("Executing perform method");}
}

3)实现MethodInterceptor,编写代理逻辑。

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method invoke");Object result = proxy.invokeSuper(obj, args);System.out.println("After method invoke");return result;}
}

4)使用Enhancer类创建代理对象。

import net.sf.cglib.proxy.Enhancer;public class Main {public static void main(String[] args) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(MyService.class);enhancer.setCallback(new MyMethodInterceptor());MyService proxyInstance = (MyService) enhancer.create();proxyInstance.perform();}
}

三、总结

  • JDK动态代理:适用于实现了接口的类,通过InvocationHandler处理代理逻辑。
  • CGLIB动态代理:适用于没有实现接口的类,通过继承实现代理,使用MethodInterceptor处理代理逻辑。性能更优。

动态代理在AOP(面向切面编程)、拦截器、权限控制、事务管理等领域有广泛应用,提供了灵活的方式来在运行时增强对象行为。

相关文章:

Java动态代理详解

文章目录 一、JDK动态代理1、关键类和接口2、实现步骤 二、CGLIB动态代理1、关键类2、实现步骤 三、总结 Java中的动态代理是一种设计模式&#xff0c;它允许在运行时创建代理对象&#xff0c;而不是在编译时。代理对象可以用来代理真实对象的方法调用。 Java中的动态代理主要…...

Python基础学习文档

一、Python入门 1.Python简介&#xff1a; Python是一种高级编程语言&#xff0c;用于多种应用&#xff0c;包括网站开发、数据科学、人工智能等。 Python具有语法简洁、易读性强、功能强大等特点。 2.安装Python ①访问Python官网&#xff08;https://www.python.org/&am…...

数据结构与算法笔记:基础篇 - 分治算法:谈一谈大规模计算框架MapReduce中的分治思想

概述 MapReduce 是 Google 大数据处理的三姐马车之一&#xff0c;另外两个事 GFS 和 Bigtable。它在倒排索引、PageRank 计算、网页分析等搜索引擎相关的技术中都有大量的应用。 尽管开发一个 MapReduce 看起来很高深。实际上&#xff0c;万变不离其宗&#xff0c;它的本质就…...

如何清除anaconda3缓存?

如果长期使用anaconda不清理缓存&#xff0c;会导致anaconda占用磁盘空间越来越多&#xff0c;甚至系统磁盘撑爆。 清除包缓存&#xff1a; 打开 Anaconda Prompt 或者命令行窗口。运行以下命令清除包缓存&#xff1a;conda clean --all这会清除所有的包缓存&#xff0c;释放磁…...

智慧校园发展趋势:2024年及未来教育科技展望

展望2024年及未来的教育科技领域&#xff0c;智慧校园的发展正引领着一场教育模式的深刻变革&#xff0c;其核心在于更深层次地融合技术与教育实践。随着人工智能技术的不断成熟&#xff0c;个性化学习将不再停留于表面&#xff0c;而是深入到每个学生的个性化需求之中。通过精…...

【Python机器学习系列】针对特定数据构建管道流水线进行机器学习预测(案例+源码)

这是我的第305篇原创文章。 一、引言 机器学习项目中有可以自动化的标准工作流程。在 Python scikit-learn 中&#xff0c;管道有助于明确定义和自动化这些工作流程。使用pipeline后&#xff0c;我们每一步的输出都会自动的作为下一个的输入。一套完整的机器学习应用流程如下&a…...

Python 学习 第三册 第12章 图的最优化问题

----用教授的方式学习。 目录 12.1图的最优化问题 12.1.1最短路径:深度优先搜索和广度优先搜索 12.1图的最优化问题 我们下面研究另一种最优化问题。假设你有一个航空公司航线的价格列表,其中包括美国任意两个城市之间的航班价格。假设有3个城市A、B和C,从A出发经过B到达…...

建筑工程乙级资质与工程质量控制体系的构建

1. 质量管理体系建立 ISO 9001认证&#xff1a;虽然不是直接要求&#xff0c;但许多乙级资质企业会选择通过ISO 9001质量管理体系认证&#xff0c;以标准化管理流程&#xff0c;提升质量管理水平。质量方针与目标&#xff1a;明确企业的质量方针&#xff0c;设定可量化、可追踪…...

kafka学习笔记07

Kafka高可用集群搭建节点需求规划 开放端口。 Kafka高可用集群之zookeeper集群搭建环境准备 删除之前的kafka和zookeeper。 重新进行环境部署&#xff1a; 我们解压我们的zookeeper: 编辑第一个zookeeper的配置文件: 我们重复类似的操作&#xff0c;创建三个zookeeper节点: 记…...

MQTTfx连接阿里云(详细版)

1、介绍 作为物联网开放平台&#xff0c;阿里云可谓是吸引大多数嵌入式爱好者的平台。物联网MQTT协议火热的今天&#xff0c;你使用过阿里云吗&#xff1f;本篇文章带你接触阿里云&#xff0c;实现MQTT通信。 我们在测试MQTT之前先了解下什么是MQTT协议。大家都知道它是一种发…...

Vue3使用provide和inject实现孙组件给爷组件传递数据

前言&#xff1a; 最近在研究gitHub中的一个项目并将与自己之前完成的项目进行结合&#xff0c;其中有一个功能是需要在孙组件将数据传递给爷组件&#xff0c;笔者研究后将使用总结如下&#xff1a; 具体步骤&#xff1a; 1.爷组件先定义一个空的函数传递给孙子 2.孙组件使…...

昇思25天学习打卡营第1天|基本介绍及快速入门

1.第一天学习总体复盘 1&#xff09;成功注册昇思大模型平台&#xff0c;并成功申请算力&#xff1b; 2)在jupyter环境下学习初学入门/初学教程的内容&#xff1b; 在基本介绍部分&#xff0c;快速撸了一边内容&#xff0c;有了一个基本的了解&#xff08;没理解到位的计划采用…...

C#.Net筑基-类型系统②常见类型

01、结构体类型Struct 结构体 struct 是一种用户自定义的值类型&#xff0c;常用于定义一些简单&#xff08;轻量&#xff09;的数据结构。对于一些局部使用的数据结构&#xff0c;优先使用结构体&#xff0c;效率要高很多。 可以有构造函数&#xff0c;也可以没有。因此初始…...

【人机交互 复习】第5章 交互式系统的需求

产品特性和用户个体差异引起的不同需求。 一、产品特性 1.功能不同 &#xff08;1&#xff09;智能冰箱&#xff1a;应能够提示黄油已用完 &#xff08;2&#xff09;字处理器&#xff1a;系统应支持多种格式 2.物理条件不同 &#xff08;1&#xff09;移动设备运行的系统应尽…...

知识的补充

目录 电容和电感的基本性质 高频电路中电容与电感的等效电路 阻抗与导纳 常用单位转换 电容和电感的基本性质 电容C是两个平板比较直&#xff0c;i也比较直&#xff0c;C的 i 随 u 的变化率变化&#xff0c;i 的相位超前。 电感L是个线圈比较弯曲&#xff0c;u也比较弯&…...

微信小程序请求服务器报ERR_CONNECTION_RESET

排查思路 1.域名是否配置或跳过 2.域名是否备案 3.证书是否有效 4.服务器中间件配置证书是否生效 5.服务器中间件转发配置是否生效 6.接口是否正常 本人遇到问题描述&#xff0c;通过浏览器访问本人网站&#xff0c;https&#xff0c;get请求可以通&#xff0c;小程序wx…...

SpringMVC:拦截Mybatis的mapper

我们在使用mybatis的时候会碰到一些公共添加时间&#xff0c;操作人员&#xff0c;更新时间、或者一些分页这个使我们如果要去添加每个对应的- service - dao - mapper - xml 这样就造成很多冗余代码&#xff0c;那这个时候我们就需要使用一些通用方法&#xff0c;统一就行修改…...

MySQL查询性能优化解决方案

解决方案 主键与默认常用查询字段建立索引&#xff0c;普通字段类型选择 UNIQUE&#xff0c;索引方法 BTREE &#xff1b;长文本使用 FULLTEXT&#xff0c;索引方法为无&#xff1b; 新建表时引擎默认设置为 MyISAM&#xff0c;不使用 InnoDB&#xff0c;因为 MyISAM 支持 MAT…...

系统安全(补充)

拒绝服务漏洞&#xff08;拒绝服务漏洞将导致网络设备停止服务&#xff0c;危害网络服务可用性&#xff09;旁路&#xff08;旁路漏洞绕过网络设备的安全机制&#xff0c;使得安全措施没有效果&#xff09;代码执行&#xff08;该类漏洞使得攻击者可以控制网络设备&#xff0c;…...

腾讯云[HiFlow】| 自动化 -------HiFlow:还在复制粘贴?

文章目录 前言&#xff1a;一&#xff1a;HiFlow是什么二&#xff1a;功能介绍1.全连接2.自动化2.1定时处理特定任务2.2实时同步变更信息2.3及时获取通知提醒 3.零代码4.多场景5.可信赖 三&#xff1a;用户体验最后 前言&#xff1a; 随着网络时代的不断发展&#xff0c;自动化…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...