代理模式如何优化Java代码,适用于什么样的场景?以及它的Java实现是怎样的
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
代理模式在Java编程中是一种常用的设计模式,它通过提供一个代理类来控制对另一个对象(目标对象)的访问。这种模式可以用于多种场景,比如延迟初始化、方法调用的预处理和后处理、权限控制、日志记录、性能监控等。代理模式主要分为静态代理和动态代理两种实现方式。
静态代理是在编译期间就确定了代理类,需要为每个目标类手动编写代理类。
// 目标接口
interface Subject {
    void request();
}
// 实际主题类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}
// 静态代理类
class StaticProxy implements Subject {
    private final RealSubject realSubject;
    public StaticProxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }
    @Override
    public void request() {
        // 预处理
        System.out.println("StaticProxy: Preprocessing before calling real subject.");
        
        realSubject.request();
        
        // 后处理
        System.out.println("StaticProxy: Postprocessing after calling real subject.");
    }
}
public class ProxyDemo {
    public static void main(String[] args) {
        Subject subject = new StaticProxy(new RealSubject());
        subject.request();
    }
}
动态代理是在运行时通过反射机制动态生成代理类,JDK提供的java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口可以用来实现动态代理。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 动态代理示例
class DynamicProxyHandler implements InvocationHandler {
    private final Object target;
    public DynamicProxyHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("DynamicProxyHandler: Preprocessing before method call.");
        Object result = method.invoke(target, args);
        System.out.println("DynamicProxyHandler: Postprocessing after method call.");
        return result;
    }
}
public class DynamicProxyDemo {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Subject proxySubject = (Subject) Proxy.newProxyInstance(
                RealSubject.class.getClassLoader(),
                new Class[]{Subject.class},
                new DynamicProxyHandler(realSubject)
        );
        proxySubject.request();
    }
}
动态代理更加灵活,不需要为每个目标类单独创建代理类,特别适用于需要大量代理类且这些代理类具有相似行为的情况。