代理模式是一种设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用。代理对象可以扩展目标对象的功能。代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度。
本文目录导读:
代理模式(Proxy Pattern)是一种设计模式,它为其他对象提供一种代理以控制对这个对象的访问,这种模式主要应用于需要对某个对象进行访问控制或者需要在访问对象时增加额外功能的情况,代理模式分为静态代理和动态代理两种,本文将详细介绍这两种代理模式以及在编程中的应用。
静态代理
1、定义
静态代理是指在编译时期就确定了代理类和被代理类的关系,代理类与被代理类实现相同的接口,在运行时,通过代理类来调用被代理类的方法。
2、实现
以下是一个简单的静态代理示例:
// 定义一个接口 public interface Subject { void request(); } // 被代理类实现接口 public class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject: Handling request."); } } // 代理类实现接口,并持有被代理类的引用 public class StaticProxy implements Subject { private RealSubject realSubject; @Override public void request() { if (realSubject == null) { realSubject = new RealSubject(); } preRequest(); realSubject.request(); postRequest(); } private void preRequest() { System.out.println("StaticProxy: Pre-processing before request."); } private void postRequest() { System.out.println("StaticProxy: Post-processing after request."); } }
3、应用场景
静态代理适用于对方法调用过程有特殊要求的情况,例如日志记录、权限控制等,在实际开发中,我们可以通过静态代理来实现这些功能。
动态代理
1、定义
动态代理是在程序运行时动态生成代理类的一种方式,它主要依赖于Java的反射机制,动态代理可以实现AOP(面向切面编程)功能,可以在不修改原有代码的基础上,为对象添加额外的功能。
2、实现
以下是一个简单的动态代理示例:
// 定义一个接口 public interface Subject { void request(); } // 实现接口的具体类,即被代理类 public class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject: Handling request."); } } // 实现InvocationHandler接口的动态代理类,用于处理代理对象的方法调用 public class DynamicProxy implements InvocationHandler { private Object target; // 要代理的对象 public DynamicProxy(Object target) { // 通过构造函数传入要代理的对象,注意这里的target是RealSubject类型,而不是Subject类型,因为我们在实现InvocationHandler接口时使用的是RealSubject类型的变量,这是因为Java泛型擦除的原因,所以我们需要显式地指定类型参数,这里为了简化示例,我们省略了这一步,你可以直接使用DynamicProxy<Subject>来创建一个通用的动态代理。 this.target = target; // 将要代理的对象赋值给内部变量target,这样在invoke方法中就可以直接使用this.target来调用被代理对象的方法,注意这里的this指的是DynamicProxy实例本身,而不是调用invoke方法的那个线程的栈帧中的this,如果你想要在不同的线程中使用同一个DynamicProxy实例来调用不同的被代理对象的方法,你需要自己管理这个状态,这里为了简化示例,我们省略了这一步,你可以使用ThreadLocal来存储每个线程的DynamicProxy实例,这样每个线程都会有自己的DynamicProxy实例,互不干扰。