职责链模式的作用:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
案例一
servlet 2.3 版新增了 Filter 和 FilterChain,其中 FilterChain 就是用了职责链模式。
Filter 用于在 Servlet 响应前,进行预处理、信息校验等,Filter 没有调用 doFilter 方法参数中 chain 的 doFilter 方法,调用链即停止
public interface Filter {
public void init(FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
public void destroy();
}
FilterChain 接口中只有一个方法 doFilter,用于控制下一个 Filter 的方法被调用
public interface FilterChain {
public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;
}
看下 FilterChain 的简单实现
private static class VirtualFilterChain implements FilterChain {
private final FilterChain originalChain;
private final List<? extends Filter> additionalFilters;
private int currentPosition = 0;
public VirtualFilterChain(FilterChain chain, List<? extends Filter> additionalFilters) {
this.originalChain = chain;
this.additionalFilters = additionalFilters;
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response)
throws IOException, ServletException {
if (this.currentPosition == this.additionalFilters.size()) {
this.originalChain.doFilter(request, response);
}
else {
this.currentPosition++;
Filter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}
}
案例二
Spring 中的拦截器 HandlerInterceptor
HandlerInterceptor 定义了 3 个方法 preHandle、postHandle、afterCompletion,调用时间见注释
public interface HandlerInterceptor {
//Called after HandlerMapping determined an appropriate handler object, but before HandlerAdapter invokes the handler
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
//Called after HandlerAdapter actually invoked the handler, but before the DispatcherServlet renders the view
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
// Callback after completion of request processing, that is, after renderingthe view
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
}
拦截器链 HandlerExecutionChain
public class HandlerExecutionChain {
//执行链中拦截器的 preHandle 方法,遇到返回 false,执行 triggerAfterCompletion 方法触发
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
//DispatcherServlet 中 doDispatch 方法调用,调用链中拦截器的 postHandle 方法
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
//执行链中截止到 applyPreHandle 返回 false 的 拦截器的 afterCompletion 方法
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, this.handler, ex);
}
catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
}
DispatcherServlet 中对拦截器链的调用
public class DispatcherServlet extends FrameworkServlet {
//分发 servlet 请求
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
.
.
.
//调用拦截器链的 applyPreHandle 方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
//调用拦截器链的 applyPostHandle 方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
.
.
.
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
.
.
.
//调用拦截器链的 triggerAfterCompletion 方法
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, null);
}
}
}
【Java学习资源】整理推荐
- 职责链模式在开源代码中的应用
- 命令模式在开源代码中的应用
- 策略模式在开源代码中应用
- 模板方法模式在开源代码中应用
- 组合模式在开源代码中的应用
- 享元模式在开源代码中的应用
- 外观模式在开源代码中的应用
- 装饰器模式在开源代码中的应用
- 桥接模式在开源代码中的应用
- 适配器模式在开源代码中的应用
- 代理模式在开源代码中的应用
- 原型模式在开源代码中的应用
- 建造者模式在开源代码中的应用
- 工厂模式在开源代码中的应用
- 单例模式在开源代码中的应用
- 编码规范
- 设计模式
- 重构
- 设计原则
- 面向对象到底是什么
- 代码质量有哪些评判标准?
【Java面试题与答案】整理推荐