九折技术 九折技术
首页
  • Go
  • MIT-6824
  • 算法与数据结构
  • 面向对象
  • 代码整洁
  • 重构
  • 设计模式
  • 学习
  • 技术
  • 人文
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub

HoldDie

长期有耐心,一切才刚刚开始!
首页
  • Go
  • MIT-6824
  • 算法与数据结构
  • 面向对象
  • 代码整洁
  • 重构
  • 设计模式
  • 学习
  • 技术
  • 人文
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub
  • 代码整洁

  • 重构

  • 设计模式

    • 创建型-单例模式
    • 创建型-工厂模式
    • 创建型-建造者模式
    • 创建型-原型模式
    • 结构型-代理模式
    • 结构型-桥接模式
    • 结构型-装饰器模式
    • 结构型-适配器模式
    • 结构型-门面模式
    • 结构型-组合模式
    • 结构型-享元模式
    • 行为型-观察者模式
    • 行为型-模板模式
    • 行为型-策略模式
    • 行为型-责任链模式
      • 行为型-状态模式
      • 行为型-迭代器模式
      • 行为型-访问者模式
      • 行为型-备忘录模式
      • 行为型-命令模式
      • 行为型-解释器模式
      • 行为型-中介模式
    • 架构
    • 设计模式
    holddie
    2020-09-28
    责任链模式
    为什么使用责任链模式
    责任链常见场景
    源码剖析
    代码实现
    思考问题

    行为型-责任链模式

    # 责任链模式

    • Chain Of Responsibility Design Pattern
    • 将请求的发送和接受解耦,让多个接收对象都有机会处理这个请求,将这些接收对象串成一条链,并沿着这条链传递这个请求,知道链上的某个接收对象能够处理它为止。
    • 在职责链模式中,多个处理器依次处理同一个请求。
    • 一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。
    • 职责链模式有两种常用的实现。一种是使用链表来存储处理器,另一种是使用数组来存储处理器,后面一种实现方式更加简单。

    # 为什么使用责任链模式

    • 可以在不修改框架源码的情况下,基于扩展点定制化框架的功能。
    • 需要一连串的逻辑判断的场景。

    # 责任链常见场景

    • 鉴权
    • 限流
    • 记录日志
    • 验证参数

    # 源码剖析

    # Servlet Filter

    # 工作原理
    image-20201014181501227
    # 源码实现
    
    public class LogFilter implements Filter {
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
        // 在创建Filter时自动调用,
        // 其中filterConfig包含这个Filter的配置参数,比如name之类的(从配置文件中读取的)
      }
    
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("拦截客户端发送来的请求.");
        chain.doFilter(request, response);
        System.out.println("拦截发送给客户端的响应.");
      }
    
      @Override
      public void destroy() {
        // 在销毁Filter时自动调用
      }
    }
    
    // 在web.xml配置文件中如下配置:
    <filter>
      <filter-name>logFilter</filter-name>
      <filter-class>com.xzg.cd.LogFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>logFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    # Spring Interceptor

    # 实现原理
    image-20201014181814131
    # 源码实现
    
    public class LogInterceptor implements HandlerInterceptor {
    
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截客户端发送来的请求.");
        return true; // 继续后续的处理
      }
    
      @Override
      public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截发送给客户端的响应.");
      }
    
      @Override
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("这里总是被执行.");
      }
    }
    
    //在Spring MVC配置文件中配置interceptors
    <mvc:interceptors>
       <mvc:interceptor>
           <mvc:mapping path="/*"/>
           <bean class="com.xzg.cd.LogInterceptor" />
       </mvc:interceptor>
    </mvc:interceptors>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    # 代码实现

    
    public abstract class Handler {
      protected Handler successor = null;
    
      public void setSuccessor(Handler successor) {
        this.successor = successor;
      }
    
      public final void handle() {
        doHandle();
        if (successor != null) {
          successor.handle();
        }
      }
    
      protected abstract void doHandle();
    }
    
    public class HandlerA extends Handler {
      @Override
      protected void doHandle() {
        //...
      }
    }
    
    public class HandlerB extends Handler {
      @Override
      protected void doHandle() {
        //...
      }
    }
    
    public class HandlerChain {
      private Handler head = null;
      private Handler tail = null;
    
      public void addHandler(Handler handler) {
        handler.setSuccessor(null);
    
        if (head == null) {
          head = handler;
          tail = handler;
          return;
        }
    
        tail.setSuccessor(handler);
        tail = handler;
      }
    
      public void handle() {
        if (head != null) {
          head.handle();
        }
      }
    }
    
    // 使用举例
    public class Application {
      public static void main(String[] args) {
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.handle();
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65

    # 思考问题

    # 对于 AOP、Servlet Filter、Spring Interceptor 三者区别

    • Filter 可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息;
    • Interceptor 可以拿到你请求的控制器和方法,却拿不到请求方法的参数;
    • Aop 可以拿到方法的参数,但是却拿不到http请求和响应的对象
    编辑
    #责任链模式
    上次更新: 2020/10/18, 14:10:00
    行为型-策略模式
    行为型-状态模式

    ← 行为型-策略模式 行为型-状态模式→

    最近更新
    01
    行为型-访问者模式
    11-24
    02
    行为型-备忘录模式
    11-24
    03
    行为型-命令模式
    11-24
    更多文章>

    Gitalking ...

    Theme by Vdoing | Copyright © 2019-2025 HoldDie | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式