介绍
定义:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. 将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
适用场景:一个请求的处理需要多个对象中的一个或几个协作处理。
优点:
- 请求的发送者和接受者解耦。
- 可以动态组合。
示例
方式 1
Handler 负责下一 Handler 的调用。
////
public abstract class Handler{protected Handler successor = null;public void setSuccessor(Handler successor) {this.successor = successor;}public final void handle() {boolean handled = doHandle();if (successor != null && !handled) {successor.handle();}}protected abstract boolean doHandle();}public class HandlerA extends Handler{@Overrideprotected boolean doHandle() {boolean handled = false;//...return handled;}}public class HandlerB extends Handler{@Overrideprotected boolean doHandle() {boolean handled = false;//...return handled;}}public class HandlerChain{private Handler head = null;private Handler tail = null;public void addHandler(Handler handler) {handler.setSuccessor(null);if (head == null) {head = handler;tail = handler;return;}tail.setSuccessor(handler);tail = handler;}public void handle() {if (head != null) {head.handle();}}}// 使用举例public class Application{public static void main(String[] args) {HandlerChain chain = new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();}}
方式 2
HandlerChain 负责下一 Handler 的调用。
public interface IHandler {
boolean handle();
}
public class HandlerA implements IHandler {
@Override
public boolean handle() {
boolean handled = false;
//…
return handled;
}
}
public class HandlerB implements IHandler {
@Override
public boolean handle() {
boolean handled = false;
//…
return handled;
}
}
public class HandlerChain {
private List
public void addHandler(IHandler handler) {
this.handlers.add(handler);
}
public void handle() {
for (IHandler handler : handlers) {
boolean handled = handler.handle();
if (handled) {
break;
}
}
}
}
// 使用举例
public class Application {
public static void main(String[] args) {
HandlerChain chain = new HandlerChain();
chain.addHandler(new HandlerA());
chain.addHandler(new HandlerB());
chain.handle();
}
}
源码
Servlet Filter
26 行的本质是递归调用,目的是为了可以实现双向拦截。
// javax.servlet
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();
}
public interface FilterChain {
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException;
}
// Tomcat 的实现
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 的 mock 实现,org.springframework.mock.web
public class MockFilterChain implements FilterChain {
private final List
@Override
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
Assert.notNull(request, “Request must not be null”);
Assert.notNull(response, “Response must not be null”);
if (this.request != null) {
throw new IllegalStateException(“This FilterChain has already been called!”);
}
if (this.iterator == null) {
this.iterator = this.filters.iterator();
}
if (this.iterator.hasNext()) {
Filter nextFilter = this.iterator.next();
nextFilter.doFilter(request, response, this);
}
this.request = request;
this.response = response;
}
}
// ch.qos.logback.classic.selector.servletpublic class LoggerContextFilter implements Filter{public void destroy() {//do nothing}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();ContextJNDISelector sel = null;if (selector instanceof ContextJNDISelector) {sel = (ContextJNDISelector) selector;sel.setLocalContext(lc);}try {chain.doFilter(request, response);} finally {if (sel != null) {sel.removeLocalContext();}}}public void init(FilterConfig arg0) throws ServletException {//do nothing}}
Spring Interceptor
DispatcherServlet 的 doDispatch() 在真正的业务逻辑执行前后,执行 HandlerExecutionChain 中的 applyPreHandle() 和 applyPostHandle() 函数。
/
public class HandlerExecutionChain{private final Object handler;private HandlerInterceptor[] interceptors;public void addInterceptor(HandlerInterceptor interceptor) {initInterceptorList().add(interceptor);}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;}}}return true;}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);}}}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);}}}}}
