Java 代理模式

熟悉设计模式的人对于代理模式可能都不陌生。那什么事代理呢,例如我们要买一件国外的商品,但是自己买不到只能去找代购,这个代购就是我们的代理。我们来了解下java中的代理

静态代理


我们来举一个开车的例子,

首先定义一辆车

Java 代理模式

再新建一个具体实现类

Java 代理模式

这个时候启动汽车

Java 代理模式

输出

汽车发动

这个时候我们想在汽车发动前系上安全带,汽车发动后开始加速

我们可以这么写

Java 代理模式

这个时候我们再启动汽车

Java 代理模式

输出:

系安全带
汽车发动
加速前进

这里的CarProxy就是CarImpl的代理,CarImpl委托CarProxy实现启动前后的逻辑

动态代理


静态代理虽然好用,但是还是不够灵活。如果这个时候我在Car 再加一个刹车的方法,那么CarProxy也要实现相应的方法,这样的耦合性太强了。所以这个时候就需要介绍下另一种代理模式  动态代理

什么事动态代理呢?动态代理是在实现阶段不用关心代理谁,而在运行阶段才能确定代理那个对象?简单来说,动态代理不用自己写代理类

1.JDK代理

还是开车,我们再写一个代理类

Java 代理模式

刚开始看到可能会觉得很奇怪,这个类怎么开车呢,简而言之,这个类怎么才能代理Car的start方法呢。

这里主要用到了反射,JdkDynamicCarProxy调用方法时会调用invoke方法,通过反射代理原对象

Java 代理模式

同时,JdkDynamicCarProxy这个并不是代理类,他只是一个代理策略,我们不能只通过他实现代理

好,具体的我们开次车就知道了

我们首先要生成一个代理策略

Java 代理模式

再生成一个代理类,这里我们通过Proxy生成,这里有三个参数

参数1:ClassLoader
参数2:该实现类的所有接口
参数3:动态代理对象

Java 代理模式

合起来,现在的开车流程变成了

Java 代理模式

每次都要这一堆代码太浪费时间了,我们把它简化下,在JdkDynamicCarProxy中新加一个方法获取代理类

Java 代理模式

现在开次车的流程变成了

Java 代理模式

2.cglib代理


我们先新建一个代理策略类

Java 代理模式

这里需要实现 CGLib 给我们提供的 MethodInterceptor 实现类,并填充 intercept() 方法。方法中最后一个 MethodProxy 类型的参数 proxy,值得注意!CGLib 给我们提供的是方法级别的代理,也可以理解为对方法的拦截

跟jdk代理一样,我们需要新建一个代理类,这里我们通过Enhancer

Java 代理模式

Enhancer允许为非接口类型创建一个Java代理。Enhancer动态创建了给定类型的子类但是拦截了所有的方法。

现在开次车的流程变成了

Java 代理模式

感觉每次用都要new特别浪费

用单例模式改造下

Java 代理模式

现在开次车的流程变成了

Java 代理模式

好了,关于代理就介绍到这。

上一篇:python测试开发django-57.xadmin选项二级联动


下一篇:深入理解CSS系列(一):理解CSS的盒子模型