博客
关于我
职责链模式在开源代码中的应用
阅读量:607 次
发布时间:2019-03-12

本文共 4158 字,大约阅读时间需要 13 分钟。

职责链模式的作用是将请求从链中的一个对象传递到下一个对象,直到请求最终被响应处理为止。这种设计方式能够有效地去除对象之间的耦合,使系统更加灵活和可扩展。

案例一:Servlet中的Filter链

在Servlet 2.3版本中,Filter和FilterChain接口被引入,其中FilterChain实现了职责链模式。Filter接口定义了一个doFilter方法,但如果链中没有其他Filter,则调用链将停止执行。下面是Filter和FilterChain的接口定义:

public interface Filter {    void init(FilterConfig filterConfig) throws ServletException;    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;    void destroy();}

FilterChain接口仅定义了一个方法doFilter,用来控制下一个Filter的执行顺序。下面的代码展示了FilterChain的简单实现,称为VirtualFilterChain,它负责管理额外的Filter和原有的Filter链:

private static class VirtualFilterChain implements FilterChain {    private final FilterChain originalChain;    private final List
additionalFilters; private int currentPosition = 0; public VirtualFilterChain(FilterChain chain, List
additionalFilters) { this.originalChain = chain; this.additionalFilters = additionalFilters; } @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { if (this.currentPosition == this.additionalFilters.size()) { this.originalChain.doFilter(request, response); } else { this.currentPosition++; Filter nextFilter = this.additionalFilters.get(this.currentPosition - 1); nextFilter.doFilter(request, response, this); } }}

这种实现方式允许开发者灵活地管理多个Filter,并确保它们按正确的顺序执行。


案例二:Spring中的拦截器链

在Spring框架中,HandlerInterceptor和HandlerExecutionChain也采用了职责链模式。HandlerInterceptor定义了三个关键方法:

  • preHandle:在处理请求之前执行。
  • postHandle:在响应生成之后执行。
  • afterCompletion:在请求处理完成后执行。

HandlerExecutionChain管理多个拦截器,并按特定顺序调用它们。以下是HandlerExecutionChain的关键实现代码:

public class HandlerExecutionChain {    private HandlerInterceptor[] interceptors;    private int interceptorIndex;    public void applyPreHandle(HttpServletRequest request, HttpServletResponse response)         throws Exception {        if (!this.interceptors Empty(interceptors)) {            for (int i = 0; i < interceptors.length; i++) {                HandlerInterceptor interceptor = interceptors[i];                if (!interceptor.preHandle(request, response, this)) {                    triggerAfterCompletion(request, response, null);                    return false;                }                this.interceptorIndex = i;            }        }        return true;    }    public void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv)         throws Exception {        if (!this.interceptors Empty(interceptors)) {            for (int i = interceptors.length - 1; i >= 0; i--) {                HandlerInterceptor interceptor = interceptors[i];                interceptor.postHandle(request, response, this.handler, mv);            }        }    }    public void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)         throws Exception {        if (!this.interceptors Empty(interceptors)) {            for (int i = this.interceptorIndex; i >= 0; i--) {                HandlerInterceptor interceptor = interceptors[i];                try {                    interceptor.afterCompletion(request, response, this.handler, ex);                } catch (Throwable ex2) {                    logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);                }            }        }    }}

DispatcherServlet在调用HandlerAdapter之前,会调用HandlerExecutionChain的applyPreHandle方法,并在响应生成后调用applyPostHandle方法。需要注意的是,如果applyPreHandle返回false,会触发afterCompletion方法处理异常情况。


【Java学习资源】整理推荐

以下是一些经典的Java学习资源推荐:

  • 《Effective Java》:这本书系统讲解了Java语言的最佳实践。
  • 《Java Concurrency in Practice》:深入探讨Java的并发编程。
  • 《The Java Collections Library》:全面理解Java集合框架。
  • 《Clean Architecture》:指导构建可维护的软件架构。
  • 《 Design Patterns》:学习经典的设计模式。

  • 【Java面试题与答案】整理推荐

    以下是一些常见的Java面试题及其答案:

  • What is the difference between List and Collection?
    • List是有序集合,支持快速随机访问,而Collection是无序集合。
  • Explain singleton enum in Java.
    • enum的单例模式通过static字段实现。
  • How to handle thread safety in Java concurrency.
    • 使用synchronized关键字、 lock锁、夹缝锁等。

  • 通过上述案例,可以清晰地看到职责链模式在不同框架中的应用和优势。在实际开发中,它能够有效地降低代码耦合度,提高系统的扩展性和可维护性。

    转载地址:http://fgaxz.baihongyu.com/

    你可能感兴趣的文章
    Mysql 数据类型一日期
    查看>>
    MySQL 数据类型和属性
    查看>>
    mysql 敲错命令 想取消怎么办?
    查看>>
    Mysql 整形列的字节与存储范围
    查看>>
    mysql 断电数据损坏,无法启动
    查看>>
    MySQL 日期时间类型的选择
    查看>>
    Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
    查看>>
    MySQL 是如何加锁的?
    查看>>
    MySQL 是怎样运行的 - InnoDB数据页结构
    查看>>
    mysql 更新子表_mysql 在update中实现子查询的方式
    查看>>
    MySQL 有什么优点?
    查看>>
    mysql 权限整理记录
    查看>>
    mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
    查看>>
    MYSQL 查看最大连接数和修改最大连接数
    查看>>
    MySQL 查看有哪些表
    查看>>
    mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
    查看>>
    MySql 查询以逗号分隔的字符串的方法(正则)
    查看>>
    MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
    查看>>
    mysql 查询数据库所有表的字段信息
    查看>>
    【Java基础】什么是面向对象?
    查看>>