首页 > 编程笔记 > Java笔记

责任链模式在JDK源码中的应用

本节主要介绍责任链模式在 JDK 中的应用。下面来看一个 JDK 中常见的 Filter 类,源码如下。
public interface Filter {
    void init(FilterConfig var1) throws ServletException;

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    void destroy();
}
Filter 接口的定义非常简单,相当于责任链模式中的 Handler 抽象角色,那么它是如何形成一条责任链的呢?可以看到 doFilter() 方法的最后一个参数类型是 FilterChain。下面来看 FilterChain 接口。

FilterChain 是 J2EE 规范定义的一个拦截器接口,源码如下。
public interface FilterChain {
    void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}
可以看到,FilterChain 类中只定义了一个 doFilter() 方法,并没有维护一个链里面的下一个对象,那么它们是怎么串联成一个责任链,实现链路传递的呢?

实际上,J2EE 只定义了一个规范,具体处理逻辑是由使用者自己来实现的。下面来看一下 Spring 中实现了 FilterChain 接口的 MockFilterChain 类。
public class MockFilterChain implements FilterChain {

    @Nullable
    private ServletRequest request;

    @Nullable
    private ServletResponse response;

    private final List<Filter> filters;

    @Nullable
    private Iterator<Filter> iterator;

    ...

    @Override
    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        Assert.notNull(request, "Request must not be null");
        Assert.notNull(response, "Response must not be null");
        Assert.state(this.request == null, "This FilterChain has already been called!");

        if (this.iterator == null) {
            this.iterator = this.filters.iterator();
        }

        if (this.iterator.hasNext()) {
            Filter nextFilter = this.iterator.next();
            nextFilter.doFilter(request, response, this);
        }

        this.request = request;
        this.response = response;
    }
    ...
}
可以看出,MockFilterChain 类把链条中的所有 Filter 都放到了 List 中,子类通过 List 来构建链路,然后在调用 doFilter() 方法时循环迭代 List 来实现“链路”传递。

所有教程

优秀文章