您好,登录后才能下订单哦!
代理模式(Proxy Pattern)是Java中常用的设计模式之一,属于结构型模式。它通过创建一个代理对象来控制对目标对象的访问,从而在不改变目标对象的情况下,增强或修改其行为。代理模式的核心思想是为其他对象提供一个代理,并由代理对象控制对原对象的引用。
代理模式的主要应用场景包括: - 远程代理:为远程对象提供本地代理,隐藏网络通信细节。 - 虚拟代理:延迟创建开销较大的对象,直到真正需要时才创建。 - 保护代理:控制对敏感对象的访问权限。 - 智能引用代理:在访问对象时执行额外的操作,如记录日志、缓存等。
代理模式的结构通常包括以下角色: - Subject(抽象主题):定义目标对象和代理对象的共同接口。 - RealSubject(真实主题):实现抽象主题接口,是代理模式中的目标对象。 - Proxy(代理):实现抽象主题接口,并持有对真实主题的引用,负责控制对真实主题的访问。
静态代理是最简单的代理模式实现方式。在静态代理中,代理类和目标类都实现相同的接口,代理类通过持有目标类的实例来调用目标类的方法,并在调用前后添加额外的逻辑。
以下是一个静态代理的示例代码:
// 抽象主题接口
interface Subject {
void request();
}
// 真实主题类
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 代理类
class Proxy implements Subject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
// 前置处理
System.out.println("Proxy: Pre-processing request.");
// 调用真实主题的方法
realSubject.request();
// 后置处理
System.out.println("Proxy: Post-processing request.");
}
}
// 客户端代码
public class StaticProxyDemo {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);
proxy.request();
}
}
动态代理是Java中更灵活的代理模式实现方式。与静态代理不同,动态代理在运行时动态生成代理类,无需手动编写代理类。Java提供了两种动态代理机制:基于接口的JDK动态代理和基于类的CGLIB动态代理。
JDK动态代理是Java标准库提供的动态代理实现方式。它基于接口生成代理类,因此目标类必须实现至少一个接口。
以下是一个JDK动态代理的示例代码:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 抽象主题接口
interface Subject {
void request();
}
// 真实主题类
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 动态代理处理器
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("DynamicProxy: Pre-processing request.");
// 调用目标对象的方法
Object result = method.invoke(target, args);
// 后置处理
System.out.println("DynamicProxy: Post-processing request.");
return result;
}
}
// 客户端代码
public class JDKDynamicProxyDemo {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject proxy = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
new DynamicProxyHandler(realSubject)
);
proxy.request();
}
}
CGLIB(Code Generation Library)是一个强大的代码生成库,可以在运行时动态生成类的子类作为代理类。与JDK动态代理不同,CGLIB可以代理没有实现接口的类。
以下是一个CGLIB动态代理的示例代码:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
// 真实主题类
class RealSubject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 动态代理拦截器
class CglibProxyInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 前置处理
System.out.println("CglibProxy: Pre-processing request.");
// 调用目标对象的方法
Object result = proxy.invokeSuper(obj, args);
// 后置处理
System.out.println("CglibProxy: Post-processing request.");
return result;
}
}
// 客户端代码
public class CglibDynamicProxyDemo {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new CglibProxyInterceptor());
RealSubject proxy = (RealSubject) enhancer.create();
proxy.request();
}
}
代理模式在实际开发中有广泛的应用,以下是一些常见的应用场景:
远程代理用于隐藏网络通信细节,客户端通过代理对象访问远程服务。例如,Java RMI(远程方法调用)就是基于远程代理实现的。
虚拟代理用于延迟创建开销较大的对象。例如,在加载大图片时,可以使用虚拟代理先显示缩略图,等真正需要时再加载完整图片。
保护代理用于控制对敏感对象的访问权限。例如,在权限管理系统中,只有具有特定权限的用户才能访问某些资源。
智能引用代理用于在访问对象时执行额外的操作。例如,在访问数据库时,可以使用代理对象记录日志或缓存查询结果。
代理模式是一种强大的设计模式,通过引入代理对象,可以在不修改目标对象的情况下增强或修改其行为。静态代理实现简单,但灵活性较差;动态代理(JDK和CGLIB)则提供了更高的灵活性,适用于复杂的应用场景。
在实际开发中,应根据具体需求选择合适的代理模式实现方式。如果需要代理接口,可以选择JDK动态代理;如果需要代理类,可以选择CGLIB动态代理。通过合理使用代理模式,可以提高代码的可维护性和扩展性。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。