设计模式之代理模式

什么是代理?

代理是一种设计模式,允许通过一个代理对象来控制对另外一个对象的访问。其目的是在不改变目标对象的前提下,为其提供额外的功能或控制其访问方式。

静态代理

核心概念

  • 目标对象(Target):需要被代理的真实对象,实现了某个接口或继承了某个类。
  • 代理类(Proxy):与目标对象实现相同的接口,持有目标对象的引用,并在调用目标方法时,在方法前后插入额外逻辑。
  • 客户端(Client):通过代理类访问目标对象,无需直接依赖目标对象的具体实现。

实现方式

  1. 定义一个接口(或基类),目标对象和代理类都实现该接口。
  2. 在代理类中持有一个目标对象的引用。
  3. 在代理类的方法中,调用目标对象的方法,并在前后添加额外逻辑。

Subject.class 接口

java 复制代码
public interface Subject {
    void request();
}

SubjectReal.class

java 复制代码
public class SubjectReal implements Subject{
    @Override
    public void request() {
        System.out.println("SubjectReal Running ......");
    }
}

SubjectProxy.class

java 复制代码
public class SubjectProxy implements Subject {
    SubjectReal target;
    public SubjectProxy() {
        this.target = new SubjectReal();
    }
    @Override
    public void request() {
        System.out.println("request before");
        target.request();
        System.out.println("request after");
    }
}

测试:

java 复制代码
public class Test {
    public static void main(String[] args) {
        SubjectProxy proxy = new SubjectProxy();
        proxy.request();
    }
}

动态代理

1. 核心概念

  • 代理对象:动态生成的代理类,实现了目标对象的接口(或继承其类)。
  • 目标对象:需要被代理的真实对象。
  • 增强逻辑:在代理对象的方法调用前后插入的额外操作(如日志、事务管理等)。

2. 核心类

java.lang.reflect.Proxy类:

用于在运行时动态生成代理类。通过newProxyInstance()方法创建代理实例,需提供:

  1. 目标对象的类加载器(ClassLoader);
  2. 目标对象实现的接口列表;
  3. 一个InvocationHandler处理器对象。
InvocationHandler接口:
  • 需实现invoke方法,定义方法调用的逻辑。所有代理对象的方法调用都会被转发到此方法中处理。

​​​​​​​

说直白一点,动态代理其实就是你自己创建一个处理器类,这个类实现InvocationHandler,然后你要把你要代理的目标对象传进来,对目标对象进行增强,其实就是加点操作,通过Proxy的newProxyInstance方法创建代理实例,在创建代理实例的时候把接口方法和类加载器都传进来,这样在处理器类里面就可以拿到你代理对象的接口方法,对其进行增强,你通过代理实例调用的方法都会通过处理器进行增强。

HostService.class

java 复制代码
public interface HostService {
    void sell();
}

Host.class

java 复制代码
public class Host implements HostService{
    private String name;
    public Host(String name) {
        this.name = name;
    }
    @Override
    public void sell() {
        System.out.println(name + "房东出租房子");
    }
}

Handler.class

java 复制代码
public class ProxyHandler implements InvocationHandler {
    private Host host;

    public ProxyHandler(Host host) {
        this.host = host;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("LoggingHandler: Before method " + method.getName());
        Object result = method.invoke(host, args);
        System.out.println("LoggingHandler: After method " + method.getName());
        return result;
    }
}

通过代理实例调用增强方法:

java 复制代码
public class Test {
    public static void main(String[] args) {
        Host host = new Host("wjk");
        ProxyHandler handler = new ProxyHandler(host);
        HostService instance = (HostService) Proxy.newProxyInstance(host.getClass().getClassLoader(), host.getClass().getInterfaces(), handler);
        instance.sell();
    }
}

如有错误,欢迎指正!!!

相关推荐
AI_Cloud_推荐2 天前
DeepSeek-V4-Pro 的 4.5 和 12:不是加价,是同名不同版本
阿里云·语言模型·代理模式·ai编程·百度云
devilnumber6 天前
Java 代理模式(简单理解回顾)
java·开发语言·代理模式
驭渊的小故事8 天前
软件工程概念篇:需求、开发模型与测试模型全解析
人工智能·代理模式
king13598745508 天前
Gemini 4 Argon API 接入与迁移:模型参数、Token 价格和 Agent 测试方案
大模型·代理模式·ai agent·gemini
YumiProxy12 天前
代理IP自动切换避坑指南:会话保持、请求头与错误处理实战
网络·网络协议·tcp/ip·代理模式·ip
-dzk-14 天前
【动态规划】LC 416.分割等和子集
算法·动态规划·代理模式
步行cgn16 天前
GoF 代理模式详解
代理模式
IPdodo_1 个月前
住宅 IP 与数据中心 IP 到底差在哪:用 RDAP、BGP 和多源证据做工程判定
网络·网络安全·代理模式·ip
承渊政道1 个月前
PR-Agent鸿蒙PC适配全记录:从Python服务端代理到ArkTS原生评审客户端
python·华为·代理模式·agent·harmonyos·pc端
kruptos1 个月前
动态规划:暴力递归如何变优雅?
代理模式·算法优化·斐波那契