欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 【Java】设计模式——代理模式

【Java】设计模式——代理模式

2025/2/22 2:15:59 来源:https://blog.csdn.net/weixin_50591390/article/details/144826066  浏览:    关键词:【Java】设计模式——代理模式

引言

代理模式(Proxy Pattern)是结构型设计模式之一,旨在为其他对象提供一种代理以控制对该对象的访问。它通过为对象创建一个替代对象或代表对象,在客户端与目标对象之间插入一个中介层,从而达到某些功能,比如延迟加载、权限控制、日志记录等。

Java 中的代理模式分为两种:静态代理和动态代理。在本文中,我们将详细讨论代理模式的概念、实现方式及应用场景。


1. 代理模式概述

代理模式是指通过代理对象间接访问目标对象。代理对象在客户端和目标对象之间充当中介角色,可以对目标对象进行一些额外的处理,比如日志记录、安全控制、事务管理、懒加载等。

1.1 代理模式的组成部分

  • 主题(Subject):目标对象或者接口,通常是被代理的对象。
  • 代理对象(Proxy):负责控制对主题对象的访问,代理对象通常会调用目标对象的相应方法,可以在调用前后加入一些额外的逻辑。
  • 客户端(Client):请求代理对象而不是直接请求主题对象。

2. 代理模式的分类

2.1 静态代理

静态代理是在编译时就确定代理类和目标类的关系,代理类和目标类都实现相同的接口,代理类通过持有目标类的实例来实现方法的转发。

静态代理的优点:

  • 对目标对象的调用透明,不需要修改目标对象的代码。
  • 可以在代理类中添加一些额外的功能,比如日志、安全控制等。

静态代理的缺点:

  • 每增加一个目标类,就需要为其创建一个代理类,代理类的数量会随着目标类的增加而增多,导致代码冗余。

静态代理示例:

// 目标接口
public interface Subject {void request();
}// 目标对象
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request");}
}// 代理类
public class Proxy implements Subject {private RealSubject realSubject;public Proxy(RealSubject realSubject) {this.realSubject = realSubject;}@Overridepublic void request() {// 在代理类中添加一些额外的功能System.out.println("Proxy: Logging before request");realSubject.request();System.out.println("Proxy: Logging after request");}
}// 客户端
public class Client {public static void main(String[] args) {RealSubject realSubject = new RealSubject();Proxy proxy = new Proxy(realSubject);proxy.request();}
}

输出:

Proxy: Logging before request
RealSubject: Handling request
Proxy: Logging after request

2.2 动态代理

动态代理是在运行时生成代理对象,而不是在编译时生成。这通常使用 Java 的反射机制,通过 Proxy 类动态生成代理对象。

Java 的 java.lang.reflect.Proxy 类和 InvocationHandler 接口提供了动态代理的实现。动态代理适用于接口类型的目标对象,而不需要为每个目标对象创建代理类,具有更好的灵活性。

动态代理的优点:

  • 不需要为每个目标类编写代理类,减少了代码冗余。
  • 可以在运行时动态生成代理对象,灵活性较高。

动态代理的缺点:

  • 需要依赖反射机制,性能稍差。
  • 仅支持接口类型的目标对象。

动态代理示例:

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: Logging before request");Object result = method.invoke(target, args);System.out.println("Proxy: Logging after request");return result;}
}// 客户端
public class Client {public static void main(String[] args) {RealSubject realSubject = new RealSubject();// 创建动态代理对象Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),new DynamicProxyHandler(realSubject));proxy.request();}
}

输出:

Proxy: Logging before request
RealSubject: Handling request
Proxy: Logging after request

3.代理模式的应用场景

代理模式广泛应用于以下场景:

1.远程代理:当客户端需要访问远程服务器上的对象时,可以使用代理模式来隐藏远程对象的复杂性。例如,RMI(远程方法调用)机制中就是通过代理模式来实现远程方法调用的。

2.虚拟代理:用于延迟加载对象的创建。例如,某些大型对象的加载可能非常昂贵,因此可以通过虚拟代理来推迟对象的创建,直到实际需要时再进行加载。

3.保护代理:用于控制对某些对象的访问,通常用于实现权限控制。例如,在多用户系统中,可以通过保护代理来确保不同角色的用户访问不同级别的数据。

4.缓存代理:通过代理来缓存目标对象的计算结果,避免重复计算。例如,在计算密集型的操作中,可以通过缓存代理来提高性能。

5.智能代理:除了控制访问外,智能代理还可以在调用目标对象方法时执行一些额外的操作,如统计调用次数、管理资源等。


4. 代理模式的优缺点

优点:

  • 透明性:代理对象和真实对象通常实现相同的接口,因此客户端无需了解代理对象的存在。
  • 附加功能:在代理对象中可以添加额外的功能,如权限检查、日志记录等。
  • 降低耦合度:代理模式使得客户端和目标对象之间的关系变得更加松耦合,方便扩展和维护。

缺点:

  • 性能开销:代理模式引入了额外的代理对象,会增加方法调用的时间消耗,尤其是使用动态代理时,反射会带来一定的性能开销。
  • 代码复杂度:在某些场景下,代理模式可能导致系统中出现大量的代理类,增加了代码的复杂性。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词