责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,其主要目的是将请求的发送者和接收者解耦。这种模式创建了一系列处理器对象,每个处理器都有一个对应的处理逻辑。当一个请求到来时,这些处理器按照顺序处理请求,直到其中一个处理器成功处理请求为止。
//定义抽象处理器(Handler)
abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(String request);
}
//定义具体处理器(ConcreteHandler) HandlerA、HandlerB、HandlerC
class HandlerA extends Handler {
@Override
public void handleRequest(String request) {
if ("A".equals(request)) {
System.out.println("Handler A is processing the request");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
class HandlerB extends Handler {
@Override
public void handleRequest(String request) {
if ("B".equals(request)) {
System.out.println("Handler B is processing the request");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
class HandlerC extends Handler {
@Override
public void handleRequest(String request) {
if ("C".equals(request)) {
System.out.println("Handler C is processing the request");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
//客户端代码
public class Client {
public static void main(String[] args) {
/**客户端创建了三个具体处理器,并将它们连接成一个处理器链。当客户端向处理器链发送请求时,处理器会按照顺序处理请求,直到其中一个处理器成功处理请求为止。**/
// 创建处理器对象
Handler handlerA = new HandlerA();
Handler handlerB = new HandlerB();
Handler handlerC = new HandlerC();
// 构建处理器链
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);
// 发送请求
handlerA.handleRequest("A");
handlerA.handleRequest("B");
handlerA.handleRequest("C");
handlerA.handleRequest("D");
}
}
拦截器链(Interceptor Chain):在Spring MVC框架中,当请求经过过滤器链处理并到达Servlet之后,请求会被传递给DispatcherServlet。DispatcherServlet的主要职责是将请求分发给适当的处理器(如Controller方法)。
Spring MVC中拦截器的执行流程:
DispatcherServlet
。DispatcherServlet
根据请求获取处理器(Handler)和拦截器链(Interceptor Chain)。DispatcherServlet
遍历拦截器链,依次执行拦截器的preHandle
方法。如果某个拦截器的preHandle
方法返回false
,则中止后续拦截器和处理器的执行,并立即返回响应。preHandle
方法通常用于执行请求预处理逻辑,例如身份验证和授权检查。preHandle
方法都返回true
,则DispatcherServlet
执行处理器(Handler)来处理请求。DispatcherServlet
再次遍历拦截器链,按照相反的顺序依次执行拦截器的postHandle
方法。postHandle
方法在处理器执行之后、视图渲染之前调用,通常用于添加模型属性或对请求进行后处理。DispatcherServlet
渲染视图并返回响应。DispatcherServlet
再次遍历拦截器链,按照相反的顺序依次执行拦截器的afterCompletion
方法。afterCompletion
方法通常用于清理资源和记录日志等操作。抽象拦截处理器(Handler)
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;
void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
处理器执行链(HandlerChain)
public class HandlerExecutionChain {
private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
// 处理器对象
private final Object handler;
// 拦截器数组
private HandlerInterceptor[] interceptors;
// 拦截器列表
private List<HandlerInterceptor> interceptorList;
// 当前处理的拦截器索引
private int interceptorIndex;
public HandlerExecutionChain(Object handler) {
this(handler, (HandlerInterceptor[]) null);
}
public HandlerExecutionChain(Object handler, HandlerInterceptor... interceptors) {
this.interceptorIndex = -1;
if (handler instanceof HandlerExecutionChain) {
HandlerExecutionChain originalChain = (HandlerExecutionChain)handler;
this.handler = originalChain.getHandler();
this.interceptorList = new ArrayList();
CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);
CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);
} else {
this.handler = handler;
this.interceptors = interceptors;
}
}
public void addInterceptor(HandlerInterceptor interceptor) {
this.initInterceptorList().add(interceptor);
}
public void addInterceptors(HandlerInterceptor... interceptors) {
if (!ObjectUtils.isEmpty(interceptors)) {
this.initInterceptorList().addAll(Arrays.asList(interceptors));
}
}
private List<HandlerInterceptor> initInterceptorList() {
if (this.interceptorList == null) {
this.interceptorList = new ArrayList();
if (this.interceptors != null) {
this.interceptorList.addAll(Arrays.asList(this.interceptors));
}
}
this.interceptors = null;
return this.interceptorList;
}
public HandlerInterceptor[] getInterceptors() {
if (this.interceptors == null && this.interceptorList != null) {
this.interceptors = (HandlerInterceptor[])this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
}
return this.interceptors;
}
// 执行拦截器链中的preHandle方法
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = this.getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
this.triggerAfterCompletion(request, response, (Exception)null);
return false;
}
}
}
return true;
}
// 执行拦截器链中的postHandle方法
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
HandlerInterceptor[] interceptors = this.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);
}
}
}
// 触发拦截器链中的afterCompletion方法
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
HandlerInterceptor[] interceptors = this.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 var8) {
logger.error("HandlerInterceptor.afterCompletion threw exception", var8);
}
}
}
}
}
以下是一些责任链设计模式的典型应用场景: