大家好,我是老三。
这节我们来看一个非常重要的设计模式——代理模式,尽管我们工作中可能很少用到,但它是很多框架重要功能的基石,肘,我们开始吧。
节假日的地铁站,你是否见过有人掏出电脑,原地输出,原来是群里被疯狂@……
用户提问题,客服@我们解决,可能很多开发同学都经历过这样的场景。
用户找到客服,提出问题,客服又找到开发同学,让开发同学去解决问题,开发同学解决完,最后反馈给客服,客服再反馈到用户。
站在用户的视角,感觉就是客服解决了这个问题,这其实就是一种代理。
我们以这个例子,来看看Java怎么实现代理模式的吧。
代理模式的定义:
Provide a surrogate or placeholder for another object to control access to it.(为其他对象提供一种代理以控制对这个对象的访问。)
简单说,就是设置一个中间代理来控制访问原目标对象,达到增强原对象的功能和简化访问方式的目的。
Java实现代理模式分为两类三种,两类是静态代理
和动态代理
,动态代理又可以分为JDK动态代理
和CGLIB动态代理
。
静态代理比较简单,代理类需要实现和目标接口类一样的接口。
我们看到,通过静态代理,可以在不修改目标对象的前提下扩展目标对象的功能。
但是,它也有一些问题:
JDK动态代理利用了JDK反射机制,动态地在内存中构建代理对象,从而实现对目标对象的代理功能。
它主要用到了两个反射类的API:
我们来看看使用JDK动态代理之后的客服代理场景。
我们简单总结一下静态代理和动态代理的主要区别:
我们也观察到,JDK动态代理,目标对象必须得实现接口,也就是说它是面向接口的,假如我们不想要接口怎么办呢?
CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成,它是通过继承来实现的。
我们来看看使用Cglib之后,我们的客服代理是什么样的:
我们可以看到Cglib动态代理和JDK动态代理最大的区别就是:
我们还需要注意:
标题里说了,开源框架都在用的代理模式,那么主流的开源框架哪些地方用到了代理模式呢?——确切说是动态代理呢?
比如:
后面两期是大家期待的面渣逆袭系列,将会揭晓这两个问题的答案。
参考:
[1].《设计模式之禅》