设计模式:代理模式
设计模式:代理模式
赵海波回答
“代理模式是一种结构型设计模式,它通过为其他对象提供一个代理来控制对这个对象的访问。代理模式可以让我们在不改变目标对象的情况下,通过代理对象来控制、增强或延迟操作。
代理模式有多种类型,包括静态代理、动态代理、远程代理、虚拟代理和保护代理。以静态代理为例,代理类与目标类实现相同的接口,代理类在调用目标类方法时可以添加额外的逻辑,如日志记录或权限检查。动态代理则是在运行时生成代理类,通常使用JDK的
InvocationHandler
接口来实现。代理模式的优点包括控制对目标对象的访问、添加额外的功能、降低客户端与目标对象的耦合度。但它也会增加系统的复杂性,可能带来一定的性能开销。”
设计模式:代理模式
1. 什么是代理模式?
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供了一种代理,以控制对这个对象的访问。代理模式可以让我们在不改变目标对象的情况下,通过代理对象来控制对目标对象的访问、增强功能或延迟操作等。
在代理模式中,代理对象通常与目标对象实现相同的接口,这样客户端可以通过代理对象来访问目标对象的功能,而无需知道是否正在使用代理。
代理在原有代码乃至原业务流程都不修改的情况下,直接在业务流程中切入新代码,增加新功能, 这也和Spring的(面向切面编程)很相似
2. 代理模式的分类
代理模式根据不同的使用场景,可以分为以下几种常见类型:
静态代理(静态定义代理类)
- 简单代理模式,是动态代理的理论基础。常见使用在代理模式
动态代理(动态生成代理类,也称为Jdk自带动态代理)
- 使用反射完成代理。需要有顶层接口才能使用,常见是mybatis的mapper文件是代理
Cglib 、javaassist(字节码操作库)
- 也是使用反射完成代理,可以直接代理类(jdk动态代理不行),使用字节码技术,不能对 final类进行继承。(需要导入jar包)
3. 代理模式的结构
代理模式一般包含以下几个角色:
- 抽象主题(Subject):定义了代理类和目标类共同的接口,这样客户端可以通过接口来操作具体对象。
- 具体主题(RealSubject):实现了抽象主题接口,是实际被代理的对象。
- 代理类(Proxy):同样实现了抽象主题接口,持有对具体主题的引用,负责在客户端和具体主题之间进行交互。
4. 代理模式的实现
下面我们以静态代理和动态代理为例,分别演示如何在Java中实现代理模式。
静态代理
所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
1. 定义接口和目标对象
1 | // 抽象主题接口 |
2. 创建代理类
1 | // 代理类 |
3. 使用代理类
1 | public class Client { |
4. 运行结果
1 | Proxy: Checking access before firing a real request. |
动态代理(使用JDK)
动态代理也叫做,JDK代理、接口代理。
动态代理的对象,是利用JDK的API,动态的在内存中构建代理对象(是根据被代理的接口来动态生成代理类的class文件,并加载运行的过程),这就叫动态代理
1. 定义接口和目标对象
1 | public interface Subject { |
2. 创建动态代理处理器
1 | import java.lang.reflect.InvocationHandler; |
3. 使用动态代理
1 | public class Client { |
4. 运行结果
1 | Dynamic Proxy: Before invoking request |
cglib动态代理
指利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理
什么是CGLIB动态代理
CGLIB动态代理和jdk代理一样,使用反射完成代理,不同的是他可以直接代理类(jdk动态代理不 行,他必须目标业务类必须实现接口),CGLIB动态代理底层使用字节码技术,CGLIB动态代理不 能对 final类进行继承。(CGLIB动态代理需要导入jar包)
5.代理模式的优缺点
优点
- 控制访问:代理模式可以在不修改原有类的情况下,控制对目标对象的访问。
- 添加功能:可以在代理类中添加额外的功能,如日志记录、权限控制、延迟加载等,而不需要改变目标类。
- 解耦:通过代理模式,客户端与目标对象之间的耦合度降低,便于后续维护和扩展。
缺点
- 增加复杂性:使用代理模式会增加系统的复杂性,尤其是当代理类和目标类之间的关系比较复杂时。
- 性能开销:代理模式引入了额外的代理对象,可能会对系统的性能产生一定的影响,尤其是在频繁调用时。