请打开网站,wordpress 禁止目录浏览,公众号 商城 网站开发,贵州建设学校网站什么是代理模式
代理模式#xff08;Proxy Pattern#xff09;是设计模式中的一种结构型模式#xff0c;它为其他对象提供一种代理以控制对这个对象的访问。
代理模式有三个主要角色#xff1a;抽象主题#xff08;Subject#xff09;、真实主题#xff08;Real Subje…什么是代理模式
代理模式Proxy Pattern是设计模式中的一种结构型模式它为其他对象提供一种代理以控制对这个对象的访问。
代理模式有三个主要角色抽象主题Subject、真实主题Real Subject和代理Proxy。
抽象主题Subject定义了真实主题与代理之间的共同接口这样真实主题和代理可以互相替换使用。
真实主题Real Subject指实际要被代理的对象。
代理Proxy提供了一个与真实主题相同的接口它内部持有一个真实主题的引用并在真实主题的实例化或执行某些操作前后进行控制或扩展。
代理模式的主要目的是在不改变真实主题的情况下为其提供一个代理类来进行访问控制或增强功能。代理模式可以实现懒加载即在真正需要使用真实主题的时候才进行实例化从而节省资源和提高性能。代理模式还能提供额外的功能例如在调用真实主题的方法前后进行日志记录、安全控制、事务管理等。
代理模式可以分为静态代理和动态代理。静态代理是通过手动编写代理类来实现的而动态代理则是在运行时动态生成代理类。动态代理通常使用Java的反射机制来实现可以减少冗余代码并且对真实主题的访问完全透明。
总之代理模式提供了一种间接访问对象的方式可以控制对象的访问、增强对象的功能并且可以在不改变真实对象的情况下进行扩展。
代理模式有几种形式
在设计模式中代理模式有两种常见的形式
静态代理Static Proxy静态代理需要手动编写代理类代理类和真实主题类实现相同的接口或继承相同的父类并在代理类中持有一个真实主题类的引用。静态代理在编译时就确定了代理对象和真实对象的关系。
动态代理Dynamic Proxy动态代理在运行时动态生成代理类不需要手动编写代理类。Java中的动态代理通常使用Java反射机制实现可以通过Proxy类和InvocationHandler接口来创建动态代理对象。动态代理可以代理接口或类适用于需要代理多个不同类型对象的场景。
在静态代理和动态代理中代理类都是通过调用真实主题类的方法并在方法前后加上一些额外的逻辑如日志记录、权限验证等来控制或增强真实主题的功能。
除了静态代理和动态代理还有一些其他的代理变体形式如远程代理、虚拟代理、保护代理等这些形式根据具体的应用场景和需求进行使用。
请举一个具体的静态代理例子
假设有一个接口 Subject定义了一个抽象主题的操作方法 request()。现在我们需要用静态代理来实现在真实主题的执行前后进行日志记录。
首先定义一个 Subject 接口
public interface Subject {void request();
}接下来创建真实主题类 RealSubject实现 Subject 接口
public class RealSubject implements Subject {Overridepublic void request() {System.out.println(真实主题执行请求);}
}然后创建一个代理类 ProxySubject实现 Subject 接口并在 request() 方法的前后添加日志记录的逻辑
public class ProxySubject implements Subject {private RealSubject realSubject;public ProxySubject(RealSubject realSubject) {this.realSubject realSubject;}Overridepublic void request() {System.out.println(代理主题执行请求之前的日志记录);// 调用真实主题的方法realSubject.request();System.out.println(代理主题执行请求之后的日志记录);}
}最后我们可以通过以下代码来使用静态代理
public class Main {public static void main(String[] args) {RealSubject realSubject new RealSubject();ProxySubject proxy new ProxySubject(realSubject);proxy.request();}
}运行程序输出结果如下
代理主题执行请求之前的日志记录
真实主题执行请求
代理主题执行请求之后的日志记录可以看到通过静态代理模式我们在真实主题的执行前后添加了日志记录的逻辑实现了对真实主题的控制和功能增强而不需要修改真实主题类的代码。这是静态代理模式的一种常见应用场景。
同样的例子怎么改成动态代理模式呢
要将上述示例改为动态代理模式需使用Java的动态代理实现。首先需要借助 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口。
首先定义 Subject 接口和 RealSubject 真实主题类与上述示例相同。
接下来创建一个实现 InvocationHandler 接口的代理处理器类 ProxyHandler用于在真实主题的方法执行前后添加日志记录的逻辑。在 invoke() 方法中可以定义增强的逻辑以及调用真实主题的方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class ProxyHandler implements InvocationHandler {private Object realSubject;public ProxyHandler(Object realSubject) {this.realSubject realSubject;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(代理主题执行请求之前的日志记录);// 调用真实主题的方法Object result method.invoke(realSubject, args);System.out.println(代理主题执行请求之后的日志记录);return result;}
}最后可以通过以下代码来使用动态代理
import java.lang.reflect.Proxy;public class Main {public static void main(String[] args) {RealSubject realSubject new RealSubject();InvocationHandler handler new ProxyHandler(realSubject);// 创建动态代理对象Subject proxySubject (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),handler);proxySubject.request();}
}运行程序输出结果与静态代理的例子相同
代理主题执行请求之前的日志记录
真实主题执行请求
代理主题执行请求之后的日志记录可以看到通过动态代理模式我们实现了在真实主题的执行前后添加日志记录的逻辑而不需要直接操作代理类使代理对象动态生成并且能够透明地调用真实主题的方法。这是动态代理模式的一种常见应用场景。
补充说明《Head First设计模式》
java在java.lang.reflect包中有自己的代理实现方式通过相关api可以动态创建一个代理类。 通过代理类去调用被代理的方法。 因为实际代理类是在运行时创建的所以把java的这个技术叫做动态代理。 Java为我们动态创建了Proxy。我们通过实现InvocationHandler接口告诉Proxy去做什么。