代理模式是一种结构型设计模式,它允许通过代理对象控制对另一个对象的访问。在代理模式中,客户端通过代理对象访问目标对象,而不直接与目标对象交互。代理对象充当了客户端和目标对象之间的中间人,可以在访问过程中添加额外的逻辑,例如权限控制、缓存、日志记录等。
代理模式的主要目的是为了提供一种间接访问目标对象的方式,从而实现更加灵活的控制和管理。
在Java中,代理模式通常包含以下几个角色:
在Java中,代理模式有两种常见的实现方式:静态代理和动态代理。
静态代理是指在编译时就已经确定了代理关系,代理类是在编译期间就已经确定的。静态代理通常需要为每个真实主题创建一个对应的代理类,在代理类中编写额外的逻辑。
下面是一个简单的静态代理的示例代码:
interface Subject {
void request();
}
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
class Proxy implements Subject {
private RealSubject realSubject;
public Proxy() {
realSubject = new RealSubject();
}
public void request() {
// 在访问真实主题前可以添加额外的逻辑
System.out.println("Proxy: Pre-processing.");
// 调用真实主题的方法
realSubject.request();
// 在访问真实主题后可以添加额外的逻辑
System.out.println("Proxy: Post-processing.");
}
}
客户端代码
public class StaticProxyExample {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.request();
}
}
在上面这个示例中,Proxy类充当了代理,它持有一个RealSubject对象的引用,在调用request()方法时,会在访问真实主题前后添加额外的逻辑。
动态代理是在运行时根据需要动态生成代理类的一种代理模式,无需手动编写每个代理类。Java中的动态代理主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现。
下面是一个简单的动态代理的示例代码:
// 定义抽象主题接口
interface Subject {
void request();
}
// 定义真实主题
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 定义代理处理器
class ProxyHandler implements InvocationHandler {
private Object realSubject;
public ProxyHandler(Object realSubject) {
this.realSubject = realSubject;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在访问真实主题前可以添加额外的逻辑
System.out.println("Proxy: Pre-processing.");
// 调用真实主题的方法
Object result = method.invoke(realSubject, args);
// 在访问真实主题后可以添加额外的逻辑
System.out.println("Proxy: Post-processing.");
return result;
}
}
// 客户端代码
public class DynamicProxyExample {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new ProxyHandler(realSubject);
Subject proxy = (Subject) Proxy.newProxyInstance(
Subject.class.getClassLoader(),
new Class[] { Subject.class },
handler
);
proxy.request();
}
}
在上面这个示例中,ProxyHandler充当了代理处理器,它实现了InvocationHandler接口,在invoke()方法中添加了额外的逻辑。通过Proxy.newProxyInstance()方法动态生成代理对象,客户端通过代理对象访问真实主题。
代理模式在Java中有许多实际应用场景,下面介绍几个常见的应用场景:
远程代理是指客户端通过代理对象访问远程主题,而不需要直接与远程主题进行通信。远程代理可以隐藏底层网络通信的细节,使得客户端可以像调用本地对象一样调用远程对象。
例如,Java中的RMI(远程方法调用)就是一种远程代理的实现方式,客户端通过代理对象调用远程方法,而实际的方法调用是在远程服务器上执行的。
虚拟代理是指代理对象在需要时才实例化真实主题对象,而不是在初始化时就创建真实主题对象。虚拟代理通常用于延迟加载大对象或者资源密集型对象,以提高系统的性能和资源利用率。
例如,在Java Swing中,ImageIcon类可以作为虚拟代理,它在第一次显示图片时才加载真实的图片对象,而不是在创建ImageIcon对象时就加载图片。
保护代理是指代理对象控制对真实主题的访问权限,只有在满足一定条件时才允许客户端访问真实主题。保护代理通常用于实现权限控制、安全验证等功能。
例如,在企业应用中,可以使用保护代理限制对敏感数据的访问,只有经过身份验证的用户才能访问。
代理模式具有以下优点:
但是代理模式也有一些缺点:
代理模式是一种常见的设计模式,在Java编程中有着广泛的应用。通过代理模式,可以实现对目标对象的间接访问,并在访问过程中添加额外的逻辑。在实际开发中,可以根据具体的需求选择合适的代理模式实现方式,以提高系统的灵活性、性能和安全性。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。