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

晓知识: 动态代理与静态代理的区别

动态代理与静态代理的区别

代理模式是一种常见的设计模式,用于在不修改原始类的情况下扩展其功能。代理分为静态代理和动态代理两种,它们在实现方式、适用场景和灵活性上有显著差异。

静态代理

静态代理在编译时就已经确定代理类和被代理类的关系。代理类和被代理类实现相同的接口或继承相同的父类,代理类在调用被代理类方法前后可以添加额外的逻辑。

  • 实现方式:需要手动编写代理类,显式调用被代理对象的方法。
  • 优点:结构简单,容易理解和实现。
  • 缺点:每个被代理类都需要一个对应的代理类,代码冗余度高,维护成本较大。

示例代码:

// 接口
public interface Subject {void request();
}// 被代理类
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject request");}
}// 代理类
public class StaticProxy implements Subject {private RealSubject realSubject;public StaticProxy(RealSubject realSubject) {this.realSubject = realSubject;}@Overridepublic void request() {System.out.println("Before request");realSubject.request();System.out.println("After request");}
}
动态代理

动态代理在运行时动态生成代理类,无需手动编写代理类代码。Java中可以通过java.lang.reflect.Proxy或第三方库(如CGLIB)实现动态代理。

  • 实现方式:通过反射机制动态生成代理类,代理逻辑由InvocationHandler实现。
  • 优点:减少代码冗余,一个代理类可以代理多个接口或类,灵活性高。
  • 缺点:性能略低于静态代理,实现复杂度较高。

示例代码(基于JDK动态代理):

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class DynamicProxyExample {public static void main(String[] args) {RealSubject realSubject = new RealSubject();Subject proxyInstance = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before request");Object result = method.invoke(realSubject, args);System.out.println("After request");return result;}});proxyInstance.request();}
}
主要区别
  • 生成时机:静态代理在编译时生成代理类;动态代理在运行时生成代理类。
  • 代码量:静态代理需要为每个被代理类编写代理类;动态代理通过通用逻辑处理多个被代理类。
  • 灵活性:动态代理更灵活,适合代理多个类或接口;静态代理适合简单场景。
  • 性能:静态代理直接调用方法,性能更高;动态代理涉及反射调用,性能略低。
适用场景
  • 静态代理:代理逻辑简单,被代理类数量较少。
  • 动态代理:需要代理多个类或接口,或代理逻辑需要动态变化。

通过比较可以看出,动态代理更适合复杂的业务场景,而静态代理适合简单且固定的需求。

http://www.dtcms.com/a/326788.html

相关文章:

  • Android模块化架构深度解析:从设计到实践
  • 强联通分量(重制版)
  • 环境配置-拉取NVIDIA Docker镜像时出现401Unauthorized错误
  • 数据填报是什么?数据填报工具有哪些?
  • 黑马程序员mysql基础篇笔记
  • 自定义switch with icon
  • 使用Pytest进行接口自动化测试(三)
  • 深入了解torch框架
  • 数据类型 string
  • 算法题——IP地址分类与子网掩码
  • CobaltStrike安装和使用教程
  • Cobalt Strike的搭建和使用
  • JDK21虚拟线程和 Golang1.24协程的比较
  • STM32——system文件夹
  • Empire--安装、使用
  • 集团型企业如何统一管控子公司权限?
  • 奈飞工厂:算法优化实战​
  • 视频播放器哪个好用?视频播放器PotPlayer,KMP Player
  • 多轮会话记忆的核心挑战
  • 8.11下一代防火墙组网方案笔记
  • 使用MAS(Microsoft Activation Scripts)永久获得win10专业版和office全套
  • C++算法·前缀和
  • DCN之AP IGMP Snooping 原理与配置
  • P3917 异或序列 题解
  • Day01_QT编程20250811
  • while循环结合列表或字典
  • 二叉搜索树解析与实现
  • 快速设计简单嵌入式操作系统(3):动手实操,基于STC8编写单任务执行程序,感悟MCU指令的执行过程
  • USB 标准请求
  • 机器学习——KMeans聚类实战案例解析