熟悉设计模式的人对于代理模式可能都不陌生。那什么事代理呢,例如我们要买一件国外的商品,但是自己买不到只能去找代购,这个代购就是我们的代理。我们来了解下java中的代理
静态代理
我们来举一个开车的例子,
首先定义一辆车
再新建一个具体实现类
这个时候启动汽车
输出
汽车发动
这个时候我们想在汽车发动前系上安全带,汽车发动后开始加速
我们可以这么写
这个时候我们再启动汽车
输出:
系安全带
汽车发动
加速前进
这里的CarProxy就是CarImpl的代理,CarImpl委托CarProxy实现启动前后的逻辑
动态代理
静态代理虽然好用,但是还是不够灵活。如果这个时候我在Car 再加一个刹车的方法,那么CarProxy也要实现相应的方法,这样的耦合性太强了。所以这个时候就需要介绍下另一种代理模式 动态代理
什么事动态代理呢?动态代理是在实现阶段不用关心代理谁,而在运行阶段才能确定代理那个对象?简单来说,动态代理不用自己写代理类
1.JDK代理
还是开车,我们再写一个代理类
刚开始看到可能会觉得很奇怪,这个类怎么开车呢,简而言之,这个类怎么才能代理Car的start方法呢。
这里主要用到了反射,JdkDynamicCarProxy调用方法时会调用invoke方法,通过反射代理原对象
同时,JdkDynamicCarProxy这个并不是代理类,他只是一个代理策略,我们不能只通过他实现代理
好,具体的我们开次车就知道了
我们首先要生成一个代理策略
再生成一个代理类,这里我们通过Proxy生成,这里有三个参数
参数1:ClassLoader
参数2:该实现类的所有接口
参数3:动态代理对象
合起来,现在的开车流程变成了
每次都要这一堆代码太浪费时间了,我们把它简化下,在JdkDynamicCarProxy中新加一个方法获取代理类
现在开次车的流程变成了
2.cglib代理
我们先新建一个代理策略类
这里需要实现 CGLib 给我们提供的 MethodInterceptor 实现类,并填充 intercept() 方法。方法中最后一个 MethodProxy 类型的参数 proxy,值得注意!CGLib 给我们提供的是方法级别的代理,也可以理解为对方法的拦截
跟jdk代理一样,我们需要新建一个代理类,这里我们通过Enhancer
Enhancer允许为非接口类型创建一个Java代理。Enhancer动态创建了给定类型的子类但是拦截了所有的方法。
现在开次车的流程变成了
感觉每次用都要new特别浪费
用单例模式改造下
现在开次车的流程变成了
好了,关于代理就介绍到这。