原理和实现
职责链模式的英文翻译是 Chain Of Responsibility Design Pattern:::color3 什么是职责链模式?
将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。 在职责链模式中,多个处理器(也就是刚刚定义中说的“接收对象”)依次处理同一个请求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。:::
框架中常用的过滤器、拦截器
https://time.geekbang.org/column/article/217395
职责链模式常用在框架的开发中,为框架提供扩展点,让框架的使用者在不修改框架源码的情况下,基于扩展点添加新的功能。实际上,更具体点来说,职责链模式最常用来开发框架的过滤器和拦截器。Servlet Filter
Servlet Filter 是 Java Servlet 规范中定义的组件,翻译成中文就是过滤器,它可以实现对 HTTP 请求的过滤功能,比如鉴权、限流、记录日志、验证参数等等。
public final class ApplicationFilterChain implements FilterChain {
private int pos = 0; //当前执行到了哪个filter
private int n; //filter的个数
private ApplicationFilterConfig[] filters;
private Servlet servlet;
@Override
public void doFilter(ServletRequest request, ServletResponse response) {
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
} else {
// filter都处理完毕后,执行servlet
servlet.service(request, response);
}
}
public void addFilter(ApplicationFilterConfig filterConfig) {
for (ApplicationFilterConfig filter:filters)
if (filter==filterConfig)
return;
if (n == filters.length) {//扩容
ApplicationFilterConfig[] newFilters = new ApplicationFilterConfig[n + INCREMENT];
System.arraycopy(filters, 0, newFilters, 0, n);
filters = newFilters;
}
filters[n++] = filterConfig;
}
}
Spring Interceptor
Servlet Filter 是 Servlet 规范的一部分,实现依赖于 Web 容器。Spring Interceptor 是 Spring MVC 框架的一部分,由 Spring MVC 框架来提供实现。
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>
Core J2EE Patterns: Intercepting Filter Pattern
https://www.informit.com/articles/article.aspx?p=1398619&seqNum=3
拦截器过滤器模式
Use an Intercepting Filter as a pluggable filter to pre and postprocess requests and responses. A filter manager combines loosely coupled filters in a chain, delegating control to the appropriate filter. In this way, you can add, remove, and combine these filters in various ways without changing existing code.
使用拦截过滤器作为可插拔过滤器来预处理和后处理请求和响应。Filter Manger将松散耦合的Filter组合在一个链中,将控制委派给相应的Filter。这样,您可以通过各种方式添加、删除和组合这些过滤器,而无需更改现有代码。
过滤器使用部署描述符以声明方式控制。 部署配置文件设置过滤器链,并且可以包含特定 URL 到此过滤器链的映射。当客户端请求与配置的 URL 映射匹配的资源时,将在调用请求的目标资源之前(预处理)和/或之后(后处理)调用链中的过滤器。Client 客户
The Client sends a request to the FilterManager.客户端向
<font style="color:rgb(0, 0, 0);">FilterManager</font>
发送请求。
FilterManager 过滤器管理器
The FilterManager manages filter processing. It creates the FilterChain with the appropriate filters, in the correct order, and initiates processing.<font style="color:rgb(0, 0, 0);">FilterManager</font>
管理过滤器处理。它以正确的顺序使用适当的过滤器创建过滤器链,并启动处理。
FilterChain 过滤器链
The FilterChain is an ordered collection of independent filters.过滤器链是独立过滤器的有序集合。
FilterOne, FilterTwo
FilterOne and FilterTwo represent individual filters that are mapped to a Target. The FilterChain coordinates the processing of filters.FilterOne 和 FilterTwo 表示映射到目标的各个过滤器。过滤器链协调过滤器的处理。
Target 目标
The Target is the resource requested by the client.目标是客户端请求的资源。
SpringBoot SecurityFilterChain
https://docs.spring.io/spring-security/reference/servlet/architecture.html
SecurityFilterChain is used by FilterChainProxy to determine which Spring Security Filter instances should be invoked for the current request.
The following image shows the role of SecurityFilterChain.