介绍

定义: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 的调用。
////

  1. public abstract class Handler{
  2. protected Handler successor = null;
  3. public void setSuccessor(Handler successor) {
  4. this.successor = successor;
  5. }
  6. public final void handle() {
  7. boolean handled = doHandle();
  8. if (successor != null && !handled) {
  9. successor.handle();
  10. }
  11. }
  12. protected abstract boolean doHandle();
  13. }
  14. public class HandlerA extends Handler{
  15. @Override
  16. protected boolean doHandle() {
  17. boolean handled = false;
  18. //...
  19. return handled;
  20. }
  21. }
  22. public class HandlerB extends Handler{
  23. @Override
  24. protected boolean doHandle() {
  25. boolean handled = false;
  26. //...
  27. return handled;
  28. }
  29. }
  30. public class HandlerChain{
  31. private Handler head = null;
  32. private Handler tail = null;
  33. public void addHandler(Handler handler) {
  34. handler.setSuccessor(null);
  35. if (head == null) {
  36. head = handler;
  37. tail = handler;
  38. return;
  39. }
  40. tail.setSuccessor(handler);
  41. tail = handler;
  42. }
  43. public void handle() {
  44. if (head != null) {
  45. head.handle();
  46. }
  47. }
  48. }
  49. // 使用举例
  50. public class Application{
  51. public static void main(String[] args) {
  52. HandlerChain chain = new HandlerChain();
  53. chain.addHandler(new HandlerA());
  54. chain.addHandler(new HandlerB());
  55. chain.handle();
  56. }
  57. }

职责链 Chain of Responsibility - 图1

方式 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 handlers = new ArrayList<>();
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 filters;
@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;
}
}
职责链 Chain of Responsibility - 图2

  1. // ch.qos.logback.classic.selector.servlet
  2. public class LoggerContextFilter implements Filter{
  3. public void destroy() {
  4. //do nothing
  5. }
  6. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  7. LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
  8. ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
  9. ContextJNDISelector sel = null;
  10. if (selector instanceof ContextJNDISelector) {
  11. sel = (ContextJNDISelector) selector;
  12. sel.setLocalContext(lc);
  13. }
  14. try {
  15. chain.doFilter(request, response);
  16. } finally {
  17. if (sel != null) {
  18. sel.removeLocalContext();
  19. }
  20. }
  21. }
  22. public void init(FilterConfig arg0) throws ServletException {
  23. //do nothing
  24. }
  25. }

Spring Interceptor

DispatcherServlet 的 doDispatch() 在真正的业务逻辑执行前后,执行 HandlerExecutionChain 中的 applyPreHandle() 和 applyPostHandle() 函数。
/

  1. public class HandlerExecutionChain{
  2. private final Object handler;
  3. private HandlerInterceptor[] interceptors;
  4. public void addInterceptor(HandlerInterceptor interceptor) {
  5. initInterceptorList().add(interceptor);
  6. }
  7. boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
  8. HandlerInterceptor[] interceptors = getInterceptors();
  9. if (!ObjectUtils.isEmpty(interceptors)) {
  10. for (int i = 0; i < interceptors.length; i++) {
  11. HandlerInterceptor interceptor = interceptors[i];
  12. if (!interceptor.preHandle(request, response, this.handler)) {
  13. triggerAfterCompletion(request, response, null);
  14. return false;
  15. }
  16. }
  17. }
  18. return true;
  19. }
  20. void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
  21. HandlerInterceptor[] interceptors = getInterceptors();
  22. if (!ObjectUtils.isEmpty(interceptors)) {
  23. for (int i = interceptors.length - 1; i >= 0; i--) {
  24. HandlerInterceptor interceptor = interceptors[i];
  25. interceptor.postHandle(request, response, this.handler, mv);
  26. }
  27. }
  28. }
  29. void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
  30. HandlerInterceptor[] interceptors = getInterceptors();
  31. if (!ObjectUtils.isEmpty(interceptors)) {
  32. for (int i = this.interceptorIndex; i >= 0; i--) {
  33. HandlerInterceptor interceptor = interceptors[i];
  34. try {
  35. interceptor.afterCompletion(request, response, this.handler, ex);
  36. } catch (Throwable ex2) {
  37. logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
  38. }
  39. }
  40. }
  41. }
  42. }