前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你有被代理过吗?讲讲开源框架都在用的代理模式

你有被代理过吗?讲讲开源框架都在用的代理模式

作者头像
三分恶
发布2022-03-23 10:31:06
3730
发布2022-03-23 10:31:06
举报
文章被收录于专栏:三分恶的专栏三分恶的专栏

大家好,我是老三。

这节我们来看一个非常重要的设计模式——代理模式,尽管我们工作中可能很少用到,但它是很多框架重要功能的基石,肘,我们开始吧。

引言

节假日的地铁站,你是否见过有人掏出电脑,原地输出,原来是群里被疯狂@……

用户提问题,客服@我们解决,可能很多开发同学都经历过这样的场景。

用户找到客服,提出问题,客服又找到开发同学,让开发同学去解决问题,开发同学解决完,最后反馈给客服,客服再反馈到用户。

站在用户的视角,感觉就是客服解决了这个问题,这其实就是一种代理。

用户向客服提问题
用户向客服提问题

我们以这个例子,来看看Java怎么实现代理模式的吧。

Java的三种代理模式实现

代理模式的定义:

Provide a surrogate or placeholder for another object to control access to it.(为其他对象提供一种代理以控制对这个对象的访问。)

简单说,就是设置一个中间代理来控制访问原目标对象,达到增强原对象的功能和简化访问方式的目的。

代理模式通用类图
代理模式通用类图

Java实现代理模式分为两类三种,两类是静态代理动态代理,动态代理又可以分为JDK动态代理CGLIB动态代理

Java实现代理模式
Java实现代理模式

静态代理

静态代理比较简单,代理类需要实现和目标接口类一样的接口。

Solver静态代理类图
Solver静态代理类图

我们看到,通过静态代理,可以在不修改目标对象的前提下扩展目标对象的功能。

但是,它也有一些问题:

  • 冗余:由于代理对象要实现与目标对象一致的接口,会产生过多的代理类。
  • 维护性不佳:一旦接口增加方法,目标对象与代理对象都要进行修改。

JDK动态代理

JDK动态代理利用了JDK反射机制,动态地在内存中构建代理对象,从而实现对目标对象的代理功能。

它主要用到了两个反射类的API:

  • java.lang.reflect Proxy| static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h):返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
  • java.lang.reflect InvocationHandler|Object invoke(Object proxy, Method method, Object[] args) :在代理实例上调用目标方法,并返回结果。

我们来看看使用JDK动态代理之后的客服代理场景。

JDK动态代理类图
JDK动态代理类图

我们简单总结一下静态代理和动态代理的主要区别:

静态代理动态代理最主要区别
静态代理动态代理最主要区别
  • 静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件
  • 动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中

我们也观察到,JDK动态代理,目标对象必须得实现接口,也就是说它是面向接口的,假如我们不想要接口怎么办呢?

Cglib动态代理

CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成,它是通过继承来实现的。

我们来看看使用Cglib之后,我们的客服代理是什么样的:

Cglib动态代理类图
Cglib动态代理类图

我们可以看到Cglib动态代理和JDK动态代理最大的区别就是:

  • 使用JDK动态代理的对象必须实现一个或多个接口
  • 使用Cglib动态代理的对象则无需实现接口,达到代理类无侵入。

我们还需要注意:

  • CGLib不能对声明为final的方法进行代理,因为是通过继承父类的方式实现,如果父类是final的,那么就无法继承父类。

扩展:动态代理的应用

标题里说了,开源框架都在用的代理模式,那么主流的开源框架哪些地方用到了代理模式呢?——确切说是动态代理呢?

比如:

  • Spring AOP可以将一些非核心业务流程抽象成切面,帮助我们处理非主线的流程,它是怎么实现的呢?
  • 你平时用惯了的MyBatis,写了那么多Mapper接口,为什么它不用实现类就能执行SQL呢?

后面两期是大家期待的面渣逆袭系列,将会揭晓这两个问题的答案。

参考:

[1].《设计模式之禅》

[2].Java三种代理模式:静态代理、动态代理和cglib代理

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-02-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • Java的三种代理模式实现
    • 静态代理
      • JDK动态代理
        • Cglib动态代理
        • 扩展:动态代理的应用
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档