前言
使用设计模式的主要目的之一就是解耦,让程序易于维护和更好扩展。
责任链则是将处理逻辑进行解耦,将独立的处理逻辑抽取到不同的处理者中,每个处理者都能够单独修改而不影响其他处理者。
使用时,依次调用链上的处理者处理逻辑。
代码实战
Filter
过滤器是 Servlet 规范规定的,处理时机是在进入 servlet 容器之前
Filter 的 doFilter 方法第三个入参 FilterChain,即为过滤器调用链,通过它实现递归调用链上的过滤器 doFilter 方法,执行过滤处理逻辑(前置处理和后置处理)
@WebFilter (urlPatterns = "/test", filterName = "MyFilter ")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException {
//前置处理
//递归调用过滤器链上的过滤器,过滤器 doFilter 方法依次入方法栈
chain.doFilter(request, response);
//当 FilterChain 上的过滤器都执行后,就会调用 servlet 的 service 方法
//方法栈弹出 doFilter 方法,执行后置处理
//后置处理
}
@Override
public 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 {
@Autowired
private List<Handler> handleList;
/**
* 执行处理
* @param context
* @return
*/
public Object execute(Object object){
for (OrderHandleIntercept handleIntercept : handleList) {
object = handleIntercept.handle(object);
}
return object;
}
}