「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。
1.代理模式的简介
代理模式(Proxy Pattern):当因为某些原因,我们不能或者不想直接访问目标对象时(通常是为了安全考虑),我们可以给客户端和目标对象之间加一个缓冲层,我们通过访问缓冲层,间接的去访问目标对象。
代理模式不仅可以代理远程对象,还可以给被代理的对象增加一些额外的功能,降低目标对象和客户端的耦合性,提高程序的扩展性,但相应的它会增大系统开销,增大系统复杂度不易维护。
2. 静态代理
1.uml 类图
2.代码举例
- 目标对象
- 目标对象的实现类
- 代理对象
3.特点
代码简单易于实现,可以在不修改目标的前提下,实现对目标类功能的扩展,增强程序的扩展性,但当目标类修改后,代理类也要对应修改,不利于系统维护。且一个代理类只能代理一个目标对象。
3. 动态代理(jdk代理)
1. uml类图
2.代码举例
- 目标对象
- 目标对象的实现类
- 代理对象
- ClassLoader loader : 指定当前目标对象使用的类加载器, getClassLoader() 获取当前类的加载器
- Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型
- InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入
从这里我们可以看出动态代理我们只需要传入目标对象的一些信息,就可以返回一个包装后的代理对象。
注意:invoke中我们加的额外操作,对生成后的代理对象执行任何一个目标方法均生效
3.特点
相对于静态代理,它可以代理多个目标对象,且不用实现目标类接口(但目标类需要实现接口),易于维护,相对来说代码看起来会比静态代理的看起来复杂一些。这也是jdk中代理对象的常用模式。
4.cglib代理
1. uml类图
2.代码结构
注意:如果要使用cglib代理的话,需导入下图四个jar包,这是spring框架中使用的比较常见的一种代理方式,如果是在Spring框架中使用,则无需导入
3.特点
1.它代理的目标对象无需实现接口,但它本身需要实现这个 net.sf.cglib.proxy.MethodInterceptor 接口 2. 它是基于内存的动态代理,且他代理的类不能是 final 类。 3. 它代理的目标方法如果是 static/final 修饰的,则不会拦截,会执行该方法,但不会执行代理的额外操作