代理模式之Java动态代理实现方法


在Java中,动态代理是一种常用的设计模式,它允许开发者在运行时动态地创建接口的代理实例。这些代理实例在调用接口方法时,可以添加自定义的行为(如日志记录、安全检查等),而无需修改接口的实现类。

Java动态代理主要基于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。以下是一个简单的Java动态代理实现方法的示例:


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 定义一个接口,这是我们要代理的目标接口
interface Subject {
    void request();
}

// 真实对象,实现了Subject接口
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 代理类,实现了InvocationHandler接口
class ProxySubject implements InvocationHandler {
    private Object realSubject;

    public ProxySubject(Object realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在目标方法执行前可以添加自定义行为
        System.out.println("Before method: " + method.getName());

        // 调用真实对象的方法
        Object result = method.invoke(realSubject, args);

        // 在目标方法执行后可以添加自定义行为
        System.out.println("After method: " + method.getName());

        return result;
    }

    // 获取代理实例
    public static Object getProxyInstance(Object realSubject) {
        return Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            new ProxySubject(realSubject)
        );
    }
}

// 测试类
public class ProxyPatternDemo {
    public static void main(String[] args) {
        // 创建真实对象
        Subject realSubject = new RealSubject();

        // 获取代理对象
        Subject proxyInstance = (Subject) ProxySubject.getProxyInstance(realSubject);

        // 调用代理对象的方法
        proxyInstance.request();
    }
}

在这个示例中,`Subject`接口是我们想要代理的目标接口,`RealSubject`是实现了`Subject`接口的真实对象。`ProxySubject`类实现了`InvocationHandler`接口,它包含了调用真实对象方法之前的预处理和之后的后续处理逻辑。通过`Proxy.newProxyInstance`方法,我们根据真实对象的类加载器、接口数组和`InvocationHandler`实现类来动态地创建了一个代理实例。最后,在`ProxyPatternDemo`的`main`方法中,我们创建了一个真实对象和一个代理对象,并通过代理对象调用了真实对象的方法,从而展示了动态代理的效果。