设计模式 -- 代理模式

119 阅读3分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

1.代理模式的简介

代理模式(Proxy Pattern):当因为某些原因,我们不能或者不想直接访问目标对象时(通常是为了安全考虑),我们可以给客户端和目标对象之间加一个缓冲层,我们通过访问缓冲层,间接的去访问目标对象。

代理模式不仅可以代理远程对象,还可以给被代理的对象增加一些额外的功能,降低目标对象和客户端的耦合性,提高程序的扩展性,但相应的它会增大系统开销,增大系统复杂度不易维护。

2. 静态代理

1.uml 类图

image.png

2.代码举例

  1. 目标对象

image.png

  1. 目标对象的实现类

image.png

  1. 代理对象

image.png

3.特点

代码简单易于实现,可以在不修改目标的前提下,实现对目标类功能的扩展,增强程序的扩展性,但当目标类修改后,代理类也要对应修改,不利于系统维护。且一个代理类只能代理一个目标对象。

3. 动态代理(jdk代理)

1. uml类图

image.png

2.代码举例

  1. 目标对象

image.png

  1. 目标对象的实现类

image.png

  1. 代理对象

image.png

  1. ClassLoader loader : 指定当前目标对象使用的类加载器, getClassLoader() 获取当前类的加载器
  2. Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型
  3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入

从这里我们可以看出动态代理我们只需要传入目标对象的一些信息,就可以返回一个包装后的代理对象。

注意:invoke中我们加的额外操作,对生成后的代理对象执行任何一个目标方法均生效

3.特点

相对于静态代理,它可以代理多个目标对象,且不用实现目标类接口(但目标类需要实现接口),易于维护,相对来说代码看起来会比静态代理的看起来复杂一些。这也是jdk中代理对象的常用模式。

4.cglib代理

1. uml类图

image.png

2.代码结构

注意:如果要使用cglib代理的话,需导入下图四个jar包,这是spring框架中使用的比较常见的一种代理方式,如果是在Spring框架中使用,则无需导入

image.png image.png

3.特点

1.它代理的目标对象无需实现接口,但它本身需要实现这个 net.sf.cglib.proxy.MethodInterceptor 接口 2. 它是基于内存的动态代理,且他代理的类不能是 final 类。 3. 它代理的目标方法如果是 static/final 修饰的,则不会拦截,会执行该方法,但不会执行代理的额外操作