本文首发于泊浮目的专栏: https://segmentfault.com/blog...
代理模式是在编程中很是常见的设计模式.笔者在面试的过程当中也常常会问到相关的问题,可是不少同窗答的并不尽人意.在这篇文章中,笔者想和你们聊聊代理模式的应用及一些实践.程序员
先来一张图面试
咱们能够很明显的看到,代理和客户端发生了耦合,而目标端则与客户端解耦.spring
上文提到了一点,松耦合.而在任何设计模式中,他们的目的都在如下范围内:编程
这里提到了代码的复用性,也能够多嘴一句,代理模式能够帮助咱们实现The Open Closed Principle
.segmentfault
在这里,咱们能够举一个例子.Target多是一位不错的程序员,client是一家公司.在整个招聘流程中,若是Proxy是猎头,有些猎头则可能会想办法帮程序员提升身价.而若是Proxy是Hr,则可能会来杀杀价.而程序员走的流程可能一直是同样的:设计模式
咱们能够把不一样的行为(讨价还价的特殊技巧)写在不一样的Proxy里(HrProxy or 猎头Proxy),而咱们的程序员只要专心走流程就好了.网络
以Java中最经常使用的框架——Spring为例.Spring最主要提供了2个功能:框架
而咱们知道,Spring的AOP本质上是经过代理模式来作的.接下来咱们来详细聊聊Spring提供的4种类型的AOP支持:spa
前三种都是Spring AOP实现的变体,Spring AOP构建在动态代理基础之上,所以,Spring对AOP的支持局限于方法拦截。设计
而SpringAOP支持两种模式的动态代理,JDK Proxy和cglib.当Spring发现目标被代理类实现就接口时,则用JDK Proxy来实现.
代码大概长这样:
//spring aop 生成的代理 public class SpringAopTargetProxy extends Target{ public void operate(){ //spring aop method1... super.operate(); //spring aop method2... } }
而AspectJ是经过编译时编织来作的,即在编译时插代码进去.因此能够认为它基于静态代理来作AOP.
基于以上,咱们也能够推导出SpringAOP对于final
orstatic
方法是无效的.
call
和execution
有什么区别呢?
以前,咱们根据代理生成的时机来区分了静态代理和动态代理.而根据使用方式,常见则有两类:
Adapter模式适配了两种具备不一样接口(API)的对象,以使它们能够一同工做。而在Proxy模式中, Proxy角色与RealSubject角色的接口(API )是相同的(透明性)。
Decorator模式与Proxy模式在实现上很类似(好比API的一致性),不过它们的使用目的不一样——Decorator模式的目的在于增长新的功能。而在Proxy模式中,与增长新功能相比,它更注重经过设置代理人的方式来减轻本人的工做负担.