责任链模式
责任链模式
定义
-
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
-
责任链模式通过将多个处理器(处理对象)以链式结构连接起来,使得请求沿着这条链传递,直到有一个处理器处理该请求为止。
-
责任链模式允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求。
写一个简单的demo
我们将以一个简单的 请求处理流程 为例,比如一个用户请求要经过多个处理器校验,只有全部通过才认为是合法请求。
1. Handler 接口
public interface Handler {
void handle(RequestContext context);
}
2. RequestContext 请求上下文
import lombok.Data;
@Data
public class RequestContext {
private String message;
private boolean continueChain = true;
}
3. 两个 Handler 实现类
import org.springframework.stereotype.Component;
@Component
public class FirstHandler implements Handler {
@Override
public void handle(RequestContext context) {
if (!context.isContinueChain()) return;
System.out.println("FirstHandler 处理消息: " + context.getMessage());
// 可中断责任链
if (context.getMessage().contains("block")) {
context.setContinueChain(false);
System.out.println("FirstHandler 中断责任链");
}
}
}
import org.springframework.stereotype.Component;
@Component
public class SecondHandler implements Handler {
@Override
public void handle(RequestContext context) {
if (!context.isContinueChain()) return;
System.out.println("SecondHandler 处理消息: " + context.getMessage());
}
}
4. HandlerChain 自动注入所有处理器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class HandlerChain {
private final List<Handler> handlers;
@Autowired
public HandlerChain(List<Handler> handlers) {
this.handlers = handlers;
}
public void execute(RequestContext context) {
for (Handler handler : handlers) {
handler.handle(context);
if (!context.isContinueChain()) {
System.out.println("责任链已中断");
break;
}
}
}
}
5. 测试
import org.example.design_pattern.HandlerChain.HandlerChain;
import org.example.design_pattern.HandlerChain.RequestContext;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DesignPatternApplicationTests {
@Autowired
private HandlerChain handlerChain;
@Test
public void testHandlerChain(){
System.out.println("=== 测试正常流程 ===");
RequestContext context1 = new RequestContext();
context1.setMessage("hello world");
handlerChain.execute(context1);
System.out.println("\n=== 测试中断流程 ===");
RequestContext context2 = new RequestContext();
context2.setMessage("please block me");
handlerChain.execute(context2);
}
}
=== 测试正常流程 ===
FirstHandler 处理消息: hello world
SecondHandler 处理消息: hello world
=== 测试中断流程 ===
FirstHandler 处理消息: please block me
FirstHandler 中断责任链
责任链已中断
Spring中的示例
1. Spring MVC — HandlerInterceptor 责任链
org.springframework.web.servlet.HandlerInterceptor
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
作用: 每个拦截器依次处理 HTTP 请求,如果某个拦截器中断了(返回 false),后续链条就不会执行。
链管理类:org.springframework.web.servlet.HandlerExecutionChain
public class HandlerExecutionChain {
private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
private final Object handler;
private final List<HandlerInterceptor> interceptorList = new ArrayList<>();
/**
* Create a new HandlerExecutionChain.
* @param handler the handler object to execute
*/
public HandlerExecutionChain(Object handler) {
this(handler, (HandlerInterceptor[]) null);
}
....
}
2. Bean 生命周期扩展 — BeanPostProcessor 链
类名: BeanPostProcessor
作用: 在 Spring 容器创建 bean 前后调用多个扩展点,每个后处理器构成一条链。
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName);
Object postProcessAfterInitialization(Object bean, String beanName);
}
调用顺序处理类: AbstractAutowireCapableBeanFactory 中按顺序调用所有处理器。
3. Web 过滤器链(Servlet 原生)
虽然不是 Spring 自己的逻辑,但 Spring Boot 启动时注册的 Filter(如 HiddenHttpMethodFilter、CharacterEncodingFilter)本质上使用的是 Servlet 的 filter 责任链:
public interface Filter {
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);
}