返回

动态代理如何 “动” 起来?

Android

篇文章我们就将目光聚焦在动态代理模式上,来聊聊动态代理到底是如何 “动” 起来的。

动态代理,顾名思义,就是代理对象的行为可以动态改变。动态代理模式是设计模式家族中非常重要的一员,它是一种在不修改源代码的情况下为对象添加新功能的技术。这种灵活性使得动态代理非常适合用于需要扩展或修改现有代码的情况,例如添加日志、安全检查或性能监控。

动态代理的工作原理是使用一个称为“代理”的特殊类来封装被代理的对象。代理类实现了与被代理对象相同的接口,并将在客户端和被代理对象之间进行中介。当客户端调用代理对象的方法时,代理对象将拦截该调用并执行额外的逻辑,例如日志记录或安全检查。然后,代理对象将把控制权交给被代理对象,以便执行实际的方法实现。

Java 中的动态代理是由 Proxy 类和 InvocationHandler 接口实现的。Proxy 类用于创建代理对象,InvocationHandler 接口用于定义代理对象将执行的额外逻辑。

以下是一个使用动态代理模式的示例:

public interface Subject {
    void doSomething();
}

public class RealSubject implements Subject {
    @Override
    public void doSomething() {
        System.out.println("RealSubject: Doing something...");
    }
}

public class ProxySubject implements InvocationHandler {
    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("ProxySubject: Before calling doSomething()");
        Object result = method.invoke(subject, args);
        System.out.println("ProxySubject: After calling doSomething()");
        return result;
    }
}

public class Client {
    public static void main(String[] args) {
        Subject subject = new RealSubject();
        InvocationHandler handler = new ProxySubject(subject);
        Subject proxy = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
        proxy.doSomething();
    }
}

在这个示例中,RealSubject 类是我们要代理的实际对象,ProxySubject 类是代理类,它实现了 InvocationHandler 接口。Client 类是客户端,它使用代理对象 proxy 来调用 doSomething() 方法。

当客户端调用 proxy.doSomething() 方法时,代理对象 proxy 会拦截该调用并执行额外的逻辑,例如在调用 doSomething() 方法之前和之后打印一条消息。然后,代理对象将控制权交给被代理对象 subject,以便执行实际的 doSomething() 方法实现。

动态代理模式是一个非常强大的工具,它可以用于各种场景。如果您需要在不修改源代码的情况下为对象添加新功能,那么动态代理模式是一个非常好的选择。