前言
使用设计模式的主要目的之一就是解耦,让程序易于维护和更好扩展。
责任链则是将处理逻辑进行解耦,将独立的处理逻辑抽取到不同的处理者中,每个处理者都能够单独修改而不影响其他处理者。
使用时,依次调用链上的处理者处理逻辑。
代码实战
Filter
过滤器是 Servlet 规范规定的,处理时机是在进入 servlet 容器之前
Filter 的 doFilter 方法第三个入参 FilterChain,即为过滤器调用链,通过它实现递归调用链上的过滤器 doFilter 方法,执行过滤处理逻辑(前置处理和后置处理)
@WebFilter (urlPatterns = "/test", filterName = "MyFilter ")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException {//前置处理//递归调用过滤器链上的过滤器,过滤器 doFilter 方法依次入方法栈chain.doFilter(request, response);//当 FilterChain 上的过滤器都执行后,就会调用 servlet 的 service 方法//方法栈弹出 doFilter 方法,执行后置处理//后置处理}@Overridepublic void destroy() {}
}
ApplicationFilterChain 维护了过滤器配置列表和当前索引下标
ApplicationFilterChain 中 doFilter 方法里面调用私有方法 internalDoFilter,在私有方法中,根据当前索引下标调用链上的过滤器
如果过滤器都执行了,就调用 servlet
Interceptor
拦截器是 Spring 框架提供的功能,处理时机实在进入servlet 后,且在进入 controller 之前处理,具体的处理逻辑在 DispatcherServlet 的 doDispatch 中
从代码中可以看出来,拦截器的处理分为三个时机,前置处理,后置处理,以及完成后。
mappedHandler 即为拦截器调用链 HandlerExecutionChain
维护了拦截器列表和当前索引下标
调用拦截链时,其实就是遍历拦截器数组,判断是否合法
业务实战
在 Filter 和 Interceptor 中,应用的最小的颗粒度都是接口,通常它们都是用来处理一些与具体业务无关的功能
如果只需要应用在某一个方法上,在 spring 中可以依靠 IOC 容器和依赖注入来实现特定业务的责任链模式
比如在业务处理中需要对一批业务数据做各种校验
解耦出各个不同校验逻辑,注入 IOC 容器
public interface Handler {/*** 对参数进行处理* @param object* @return*/Object handle(Object object);
}/*** 指定注入顺序为1**/
@Order(1)
@Component
public class Handler1 implements Handler {//...省略
}/*** 指定注入顺序为2**/
@Order(2)
@Component
public class Handler2 implements Handler {//...省略
}/*** 指定注入顺序为3**/
@Order(3)
@Component
public class Handler3 implements Handler {//...省略
}@Component
public class HandleChain {@Autowiredprivate List<Handler> handleList;/*** 执行处理* @param context* @return*/public Object execute(Object object){for (OrderHandleIntercept handleIntercept : handleList) {object = handleIntercept.handle(object);}return object;}
}