zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

代理模式:先生需要代购吗?

代理模式 需要
2023-09-14 09:11:10 时间

“代理”这个词这几年可谓是家喻户晓了,对于“代理模式”我们也可以通过代购的逻辑来进行理解。

 

本期干货文章,我们来聊聊编程中GOF23种经典模式之一的“代理模式”,这里以java语言为例进行讲解。

 

1. 代理模式Proxy

 

代理模式是一种结构型设计模式,是开发中最常用的设计模式之一。

 

它是这样来定义的:为其他对象提供一种代理以控制对这个对象的访问。

 

代理模式主要用来解决:在直接访问对象时带来的一些问题,比如:我们需要为一个业务方法在执行前后记录日志,为了达到解耦的目的,我们就需要创建一个代理类来完成既可以调用原业务方法,又可以在调用前后进行日志处理。

 

代理模式的使用场景:在我们开发中非常的多,比如Spring容器的延迟加载,AOP增强处理、日志处理等。

 

代理模式的角色:

 

 

抽象角色: 通过接口或抽象类声明真实角色需要被代理的业务方法。

 

委托角色(真实角色): 被代理的对象,需要实现抽象角色中业务方法这样才会被代理业务方法。

 

代理角色:实现抽象角色,是真实角色的代理,通过实现抽象角色可以在真实角色实现业务的基础上添加增强功能和业务。

 

代理模式分类

●静态代理

●动态代理

 

2. 静态代理

 

静态代理就是由程序员创建或工具生成代理类的代码,再对其进行编译。

 

之所以叫静态代理是因为在程序运行之前我们代理类的.class文件就已经存在了,代理类和委托类(真实角色)的关系和方法增强在程序运行前就已经确定了。

 

下面我们通过之前说的添加日志业务为例,来看下静态代理的实现:

 

抽象角色:

 

 

委托角色:

 

 

代理角色:

 

 

静态代理的使用:

 

 

分析:

 

静态代理的特点就是在不影响真实角色业务方法的基础上进行了方法的增强,完成了业务和增强的解耦。

 

缺点是代理类和委托类实现了相同的抽象接口,这样不仅造成了代码的重复——以后我们想要新增一个业务方法的时候,代理类和委托类代码改动的也比较大,而且一个代理类也只能代理一种类型的对象,如果想要代理其他类型的对象又需要按照我们上面写的一套重新写一套。

 

为了解决静态代理的缺点,于是java中就出现了动态代理模式。

 

3. 动态代理

 

动态代理是在程序运行期间,由JVM通过反射机制或者修改字节码技术实现生成代理类对象,在实现阶段我们不用关心代理类,而在运行阶段才指定哪一个对象,因为这里的代理类不是由程序员编写的而是由系统动态生成的所以叫动态代理。

 

Java中动态代理的实现方式主要有两种:

● JDK动态代理

JDK动态代理是利用反射机制在程序运行过程中生成代理对象,JDK的动态代理只能代理实现了接口的类。

 

● CGLib动态代理

CGLib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。可以代理没有实现接口的类。

 

这两种动态代理的实现方式其实也是java经典框架spring里面使用的两种方式。

 

因为JDK动态代理是由JDK提供的所以我们可以直接使用,而CGLib是第三方开源的需要下载和导入第三方的jar包或者依赖,所以这里我们主要讲解JDK动态代理的实现。

 

JDK动态代理实现:

 

JDK动态代理实现步骤:

(1) 创建一个实现接口InvocationHandler的类;

(2) 在自定义InvocationHandler实现类中调用Proxy的newProxyInstance静态方法,创建一个代理类。

(3) 重新实现类的invoke方法,添加增强功能。

(4) 通过代理对象调用目标方法。

 

代码实现:

我们的抽象接口UserService和为拖累UserServiceImp还是不变,下面我们只需要完成InvocationHandler实现类即可。

 

 

动态代理的使用:

 

 

分析:

 

动态代理与静态代理相比较,最大的好处就是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理                                      (InvocationHandler.invoke)。

 

这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。而且动态代理的应用使我们的类职责更加单一,复用性更强。