责任链模式

责任链模式

理解:
1. 责任链类:内部持有链上处理类的集合,有特殊需求时还需要维护执行到链上第几个处理器的索引;
2. 处理接口:内部定义了处理类的规范,各个方法可以加上责任链类参数来保证是否需要完整的链式调用;
2. 链上处理类:实现处理接口,编写具体的处理方法,并根据实际的需求判断是否继续执行剩下的链上处理类;

具体应用场景:

  1. Servlet的Filter:
    1.责任链类:FilterChain拦截器链,内部维护具体的拦截器集合;
    2.处理接口:Filter
    3.链上处理类:HttpFilter, CorsFilter等
  2. Spring MVC的拦截器:
    1.责任链类:Spring MVC的DispatcherServlet中doDispatch中使用到HandlerExecutionChain这个类,它内部持有一个HandlerInterceptor集合和遍历handler并执行handler的一些方法,Spring MVC这段代码preHandle和postHandle的在责任链上的执行顺序分别是:preHanlde的执行是顺序遍历interceptor集合并执行,postHandle方法的执行是逆序遍历interceptor集合并执行;
    2.处理接口:HandlerInterceptor
    3.链上处理类:WebContentInterceptor,CorsInterceptor及自定义拦截器
    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
    // 责任链类
    public class HandlerExecutionChain {
    private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
    private final Object handler;
    @Nullable
    private HandlerInterceptor[] interceptors;
    @Nullable
    // 处理器拦截器集合
    private List<HandlerInterceptor> interceptorList;
    private int interceptorIndex;

    public HandlerExecutionChain(Object handler) {
    this(handler, (HandlerInterceptor[])null);
    }

    public HandlerExecutionChain(Object handler, @Nullable HandlerInterceptor... interceptors) {
    this.interceptorIndex = -1;
    if (handler instanceof HandlerExecutionChain) {
    HandlerExecutionChain originalChain = (HandlerExecutionChain)handler;
    this.handler = originalChain.getHandler();
    this.interceptorList = new ArrayList();
    CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);
    CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);
    } else {
    this.handler = handler;
    this.interceptors = interceptors;
    }

    }

    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HandlerInterceptor[] interceptors = this.getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
    // 顺序遍历执行interceptor的prehandle方法
    for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
    HandlerInterceptor interceptor = interceptors[i];
    if (!interceptor.preHandle(request, response, this.handler)) {
    this.triggerAfterCompletion(request, response, (Exception)null);
    return false;
    }
    }
    }

    return true;
    }

    void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
    HandlerInterceptor[] interceptors = this.getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
    // 逆序遍历执行interceptor的posthandle方法
    for(int i = interceptors.length - 1; i >= 0; --i) {
    HandlerInterceptor interceptor = interceptors[i];
    interceptor.postHandle(request, response, this.handler, mv);
    }
    }

    }

    }
1
2
3
4
5
6
7
8
9
10
11
12
// 处理接口
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}

default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}

default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 链上处理类
private class CorsInterceptor extends HandlerInterceptorAdapter implements CorsConfigurationSource {
@Nullable
private final CorsConfiguration config;

public CorsInterceptor(@Nullable CorsConfiguration config) {
this.config = config;
}

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
return asyncManager.hasConcurrentResult() ? true : AbstractHandlerMapping.this.corsProcessor.processRequest(this.config, request, response);
}

@Nullable
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
return this.config;
}
}

责任链模式使用

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
66
public class MyServlet {
public static void main(String[] args) {
Request request = new Request();
request.str = "request, <script>,我是一名java工程师,我的梦想是做一名架构师";
Response response = new Response();
response.str = "response";

FilterChain chain = new FilterChain();
chain.add(new HTMLFilter()).add(new SensitiveFilter());
chain.doFilter(request, response);
System.out.println(request.str);
System.out.println(response.str);

}
}

class Request {
String str;
}

class Response {
String str;
}

interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}

class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
request.str = request.str.replaceAll("<", "[").replaceAll(">", "]") + "HTMLFilter()";
chain.doFilter(request, response);
response.str += "--HTMLFilter()";

}
}

class SensitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
request.str = request.str.replaceAll("java", "后端") + " SensitiveFilter()";
chain.doFilter(request, response);
response.str += "--SensitiveFilter()";

}
}


class FilterChain {
List<Filter> filters = new ArrayList<>();
int index = 0;

public FilterChain add(Filter f) {
filters.add(f);
return this;
}

public void doFilter(Request request, Response response) {
if(index == filters.size()) return;
Filter f = filters.get(index);
index ++;

f.doFilter(request, response, this);
}
}