漫谈代理模式

本文首发于泊浮目的专栏: https://segmentfault.com/blog...

前言

代理模式是在编程中很是常见的设计模式.笔者在面试的过程当中也常常会问到相关的问题,可是不少同窗答的并不尽人意.在这篇文章中,笔者想和你们聊聊代理模式的应用及一些实践.程序员

What

先来一张图
面试

咱们能够很明显的看到,代理和客户端发生了耦合,而目标端则与客户端解耦.spring

Why

上文提到了一点,松耦合.而在任何设计模式中,他们的目的都在如下范围内:编程

  1. 减小代码冗余度,提升代码复用性
  2. 松耦合

这里提到了代码的复用性,也能够多嘴一句,代理模式能够帮助咱们实现The Open Closed Principle.segmentfault

在这里,咱们能够举一个例子.Target多是一位不错的程序员,client是一家公司.在整个招聘流程中,若是Proxy是猎头,有些猎头则可能会想办法帮程序员提升身价.而若是Proxy是Hr,则可能会来杀杀价.而程序员走的流程可能一直是同样的:设计模式

  1. 电面
  2. 到面
  3. 签合同

咱们能够把不一样的行为(讨价还价的特殊技巧)写在不一样的Proxy里(HrProxy or 猎头Proxy),而咱们的程序员只要专心走流程就好了.网络

How

以Java中最经常使用的框架——Spring为例.Spring最主要提供了2个功能:框架

  • IOC(Inversion of Control)
  • AOP(Aspect Oriented Programming)

而咱们知道,Spring的AOP本质上是经过代理模式来作的.接下来咱们来详细聊聊Spring提供的4种类型的AOP支持:spa

  • 基于代理的经典Spring AOP;
  • 纯POJO切面;
  • @AspectJ注解驱动的切面;
  • 注入式AspectJ切面(适用于Spring各版本)。

前三种都是Spring AOP实现的变体,Spring AOP构建在动态代理基础之上,所以,Spring对AOP的支持局限于方法拦截。设计

而SpringAOP支持两种模式的动态代理,JDK Proxy和cglib.当Spring发现目标被代理类实现就接口时,则用JDK Proxy来实现.

  • JDK Proxy不彻底经过反射来作,也有ASM进行字节码操做的.本质是经过接口约定来作的
  • cglib彻底经过ASM字节码来作.本质经过继承的方式实现

代码大概长这样:

//spring aop 生成的代理
public class SpringAopTargetProxy extends Target{
    public void  operate(){
            //spring aop method1...
            super.operate();
           //spring aop method2...
    }
}

而AspectJ是经过编译时编织来作的,即在编译时插代码进去.因此能够认为它基于静态代理来作AOP.

基于以上,咱们也能够推导出SpringAOP对于finalorstatic方法是无效的.

callexecution有什么区别呢?
  • call就是在调用这个方法的地方插入代码
  • execution就是在调用这个方法的前面插入代码

代理模式的变化形式

以前,咱们根据代理生成的时机来区分了静态代理和动态代理.而根据使用方式,常见则有两类:

  • Virtual Proxy:只有当真正须要实例时,它才生成和初始化实例
  • Remote Proxy:远程代理可让咱们没必要关心RealSubject角色是否在网络上,而是像调本地方法同样调用它的方法.Java的RMI(Remote Method Invocation)就至关于远程代理.

相似的设计模式

Adapter

Adapter模式适配了两种具备不一样接口(API)的对象,以使它们能够一同工做。而在Proxy模式中, Proxy角色与RealSubject角色的接口(API )是相同的(透明性)。

Decorator

Decorator模式与Proxy模式在实现上很类似(好比API的一致性),不过它们的使用目的不一样——Decorator模式的目的在于增长新的功能。而在Proxy模式中,与增长新功能相比,它更注重经过设置代理人的方式来减轻本人的工做负担.

相关文章
相关标签/搜索