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

静态代理和动态代理

在编程中,代理模式(Proxy Pattern)是一种设计模式,用于在不修改原始对象的情况下控制对其的访问。代理可以分为静态代理和动态代理,它们在实现方式和应用场景上有所不同。

静态代理

定义:静态代理是在编译时创建代理类。代理类和被代理类都需要在编译时就确定下来,代理类实现了与被代理类相同的接口,并在其方法中调用被代理对象的方法。这种代理模式的代理类是固定的,不能在运行时改变。

特点

  • 代理类是在编译时生成的。
  • 代理类和被代理类在编译时是已知的。
  • 代理类需要显式地实现被代理类的接口。

示例

假设有一个接口 Subject 和一个实现类 RealSubject,现在需要创建一个代理类 ProxySubject 来控制对 RealSubject 的访问。

// 接口
public interface Subject {void request();
}// 真实对象
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}// 代理对象
public class ProxySubject implements Subject {private RealSubject realSubject;public ProxySubject(RealSubject realSubject) {this.realSubject = realSubject;}@Overridepublic void request() {System.out.println("ProxySubject: Before real request.");realSubject.request();System.out.println("ProxySubject: After real request.");}
}// 客户端代码
public class Client {public static void main(String[] args) {RealSubject realSubject = new RealSubject();ProxySubject proxySubject = new ProxySubject(realSubject);proxySubject.request();}
}

输出

ProxySubject: Before real request.
RealSubject: Handling request.
ProxySubject: After real request.

在这个示例中,ProxySubject 是静态代理,它在编译时就知道需要代理哪个 RealSubject 对象。

动态代理

定义:动态代理是在运行时创建代理类。动态代理允许你在运行时生成代理对象,而不需要在编译时就确定代理类。Java 提供了 java.lang.reflect.Proxy 类和 InvocationHandler 接口来实现动态代理。

特点

  • 代理类是在运行时生成的。
  • 代理类和被代理类在运行时动态绑定。
  • 不需要显式地创建代理类,只需定义一个 InvocationHandler 实现即可。

示例

使用 Java 的动态代理来实现上述的代理功能:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 接口
public interface Subject {void request();
}// 真实对象
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}// 动态代理处理器
public class DynamicProxyHandler implements InvocationHandler {private Object target;public DynamicProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Proxy: Before real request.");Object result = method.invoke(target, args);System.out.println("Proxy: After real request.");return result;}
}// 客户端代码
public class Client {public static void main(String[] args) {RealSubject realSubject = new RealSubject();Subject proxyInstance = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),new DynamicProxyHandler(realSubject));proxyInstance.request();}
}

输出

Proxy: Before real request.
RealSubject: Handling request.
Proxy: After real request.

在这个示例中,Proxy.newProxyInstance 方法创建了一个动态代理实例,它在运行时动态处理对 RealSubject 的方法调用。

区别总结

  1. 生成方式

    • 静态代理:代理类在编译时已存在,并且需要在编写代码时显式定义。
    • 动态代理:代理类在运行时生成,可以在运行时灵活地创建和修改。
  2. 灵活性

    • 静态代理:代理类的逻辑是固定的,修改代理行为需要修改代码并重新编译。
    • 动态代理:可以通过 InvocationHandler 灵活地处理方法调用,无需修改现有代码。
  3. 使用场景

    • 静态代理:适用于代理逻辑较为固定,且代理类不需要在运行时变化的情况。
    • 动态代理:适用于代理逻辑动态变化或需要为多个类生成代理的场景,特别是在框架中经常使用。

这两种代理方式各有优缺点,根据具体需求选择适合的代理方式。


http://www.mrgr.cn/news/3437.html

相关文章:

  • JAVA_7
  • MySQL读写分离
  • MyBatis源码系列1(使用JDBC查询数据)
  • 代码随想录跟练第六天——LeetCode
  • 网际报文协议ICMP及ICMP重定向实例详解7
  • 利用贝叶斯和决策树 来进行医疗诊断的
  • ORA-01110
  • 【ARM 芯片 安全与攻击 5.6 -- 侧信道与隐蔽信道的区别】
  • uniapp-部分文件中文乱码
  • 程序员如何学习开源项目
  • PCB线宽和线间距设计PCB抄板
  • Maven 从本地文件系统加载依赖项
  • [CLIP-VIT-L + Qwen] 多模态大模型学习笔记 - 5
  • 软件测试学习笔记丨Allure2报告添加附件报告定制
  • 【Redis】哈希类型详解及缓存方式对比:从命令操作到实际应用场景
  • C:数组传参的本质
  • 【ARM系统】基础知识总结
  • 2024计算机软考报名流程(电脑报名)
  • Fx - day3 - 沙盒/更改集/互联更改集/配置包
  • django之反向关系查询<related_model>_set/related_name