描述

代理模式(Proxy Pattern) ,给某一个对象提供一个代理,并由代理对象控制对原对象的引用,对象结构型模式。这种也是静态代理 ,静态代理和包装模式非常相似

image.png

主要角色

代理模式包含如下角色:

  • Subject: 抽象主体角色(抽象类或接口)
  • Proxy: 代理主体角色(代理对象类)
  • RealSubject: 真实主体角色(被代理对象类)

代码实现-JDK动态代理

  1. public interface TikTok {
  2. String liveStreaming();
  3. }

  1. public class Lshady_TikTok implements TikTok{
  2. @Override
  3. public String liveStreaming() {
  4. return "lshady=>开始直播";
  5. }
  6. }
  1. public class ProxyTiktok implements InvocationHandler {
  2. private Object object;
  3. public ProxyTiktok(Object object) {
  4. this.object = object;
  5. }
  6. public static <T> T getProxy(T t){
  7. Object o = Proxy.newProxyInstance(
  8. t.getClass().getClassLoader(),//当前被代理对象的类加载器
  9. t.getClass().getInterfaces(),//当前被代理对象所实现的所有接口
  10. new ProxyTiktok(t));//当前被代理对象执行目标方法的时候我们使用可以定义拦截增强方法
  11. return (T)o;
  12. }
  13. //定义目标方法的拦截逻辑:每一个方法都会进来
  14. @Override
  15. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  16. System.out.println("代理对象代理直播");
  17. //接口无实现 此方法不用传入 可以实现 声明试调用 mybatis openfeign 实现原理
  18. //反射执行
  19. Object invoke = method.invoke(object);
  20. //代理对象需要增强的逻辑
  21. return invoke;
  22. }
  23. }
  1. //动态代理模式 代理对象和目标对象的相同点在于都是同一个接口
  2. public class ProxyTest {
  3. public static void main(String[] args) {
  4. TikTok lshady_tikTok = new Lshady_TikTok();
  5. lshady_tikTok.liveStreaming();
  6. TikTok proxy = ProxyTiktok.getProxy(lshady_tikTok);
  7. String s = proxy.liveStreaming();
  8. System.out.println(s);
  9. }
  10. }
  11. //测试结果
  12. 代理对象代理直播
  13. lshady=>开始直播

代码实现-cglib动态代理

  1. public class Ls_TikTok{
  2. public String liveStreaming() {
  3. return "lshady=>开始直播";
  4. }
  5. }
  1. public class CglibProxyTiktok{
  2. public static <T> T createProxy(T t){
  3. //创建一个增强器
  4. Enhancer enhancer = new Enhancer();
  5. //设置父类
  6. enhancer.setSuperclass(t.getClass());
  7. //设置回调
  8. enhancer.setCallback(new MethodInterceptor() {
  9. @Override
  10. public Object intercept(
  11. Object o,
  12. Method method,//为了能获取的原方法的一些元数据
  13. Object[] objects,
  14. MethodProxy methodProxy) throws Throwable {
  15. //编写拦截代理的逻辑
  16. System.out.println("cglib登场。。。");
  17. Object o1 = methodProxy.invokeSuper(o, objects);//执行目标方法
  18. return o1;
  19. }
  20. });
  21. //创建一个代理对象
  22. return (T) enhancer.create();
  23. }
  24. }
  1. public static void main(String[] args) {
  2. Ls_TikTok ls_tikTok = new Ls_TikTok();
  3. String s = ls_tikTok.liveStreaming();
  4. System.out.println(s);
  5. Ls_TikTok proxy = CglibProxyTiktok.createProxy(ls_tikTok);
  6. String s1 = proxy.liveStreaming();
  7. System.out.println(s1);
  8. }
  9. //测试
  10. lshady=>开始直播
  11. cglib登场。。。
  12. lshady=>开始直播

使用场景

什么场景用到?

  • MyBatis的mapper到底是什么?怎么生成的?
  • 动态代理 UserMapper、CityMapper,mybatis帮我们写实现MapperProxy Alibaba
  • Seata的DataSourceProxy是什么?
  • DruidDataSource存在的Proxy模式
  • 监控链
  • … ……