代理模式(Proxy Pattern)是设计模式中的一种结构型模式。它为其他对象提供一种代理以控制对这个对象的访问。在 Java 中,代理模式有多种实现方式,主要分为静态代理和动态代理。
1. 代理模式的基本概念
意图:代理模式通过创建一个代理对象来代替实际对象,并且可以控制对实际对象的访问。代理对象和实际对象通常实现相同的接口或继承相同的类。
结构:
- Subject(抽象主题接口/类):定义了真实对象和代理对象的公共接口或父类。
- RealSubject(真实主题类):实现了抽象主题接口,是代理对象所代表的真实对象。
- Proxy(代理类):持有一个对真实对象的引用,实现了抽象主题接口,并在调用时对真实对象进行操作。
适用场景:
- 需要对原对象的功能进行扩展或控制,而不改变原对象的代码。
- 需要对某个类的访问进行控制,比如延迟加载、安全代理、远程代理等。
2. 静态代理
特点:
- 预先定义:代理类在编译时就已经创建好了,代理类和真实类需要实现相同的接口。
- 代理行为固定:代理类的行为是静态的,不能在运行时改变。
优缺点:
- 优点:实现简单,容易理解,能够在编译时进行类型检查。
- 缺点:代理类与真实类高度耦合,代理类过多会导致代码冗余,不适合扩展性需求高的场景。
示例代码:
// 定义接口
public interface Subject {
void request();
}
// 真实主题类
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("真实主题处理请求");
}
}
// 代理类
public class Proxy implements Subject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("代理开始处理");
realSubject.request();
System.out.println("代理完成处理");
}
}
// 测试代码
public class Main {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);
proxy.request();
}
}
3. 动态代理
特点:
- 动态生成:动态代理类在运行时由 JVM 动态生成,不需要事先定义代理类。
- 灵活性高:可以在运行时灵活地决定代理行为。
实现方式:
- JDK 动态代理:基于反射机制,只能代理实现了接口的类。
- CGLIB 动态代理:基于字节码生成,可以代理没有实现接口的类,常用于 Spring 框架。
优缺点:
- 优点:减少了静态代理的冗余代码,增强了扩展性,可以动态地为多个对象创建代理。
- 缺点:性能略低于静态代理,调试较为复杂,尤其是对生成的动态代理类进行调试。
JDK 动态代理示例代码:
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 {
@Override
public void request() {
System.out.println("真实主题处理请求");
}
}
// 动态代理处理器
public class DynamicProxyHandler implements InvocationHandler {
private Object target;
public DynamicProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理开始处理");
Object result = method.invoke(target, args); // 调用真实对象的方法
System.out.println("代理完成处理");
return result;
}
}
// 测试代码
public class Main {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject proxyInstance = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
new DynamicProxyHandler(realSubject)
);
proxyInstance.request();
}
}
4. 代理模式的常见应用
- 安全代理:控制对原始对象的访问,确保安全性。
- 延迟加载:在需要时才创建或加载实际对象,以提高性能。
- 远程代理:为远程对象提供本地代理,使远程调用看起来像本地调用。
- 虚拟代理:控制对象的访问以延迟实际对象的创建和初始化。
- 保护代理:通过代理来控制对象的访问权限。
5. 总结
代理模式是一种非常有用的设计模式,它通过引入代理对象来控制对实际对象的访问。静态代理适合简单和固定的场景,而动态代理则提供了更强的灵活性和扩展性。理解代理模式的使用场景和实现方式,可以帮助开发者编写更灵活、更易维护的代码。
评论 (0)