责任链模式
问题
什么是责任链模式?Java 和 Spring 中有哪些典型应用?
答案
核心思想
将请求沿着一条处理链传递,链上的每个处理器可以决定处理请求或传递给下一个处理器。发送者无需知道哪个处理器会最终处理请求。
实现示例
责任链模式 - 请求校验链
// 处理器抽象类
public abstract class Handler {
protected Handler next;
public Handler setNext(Handler next) {
this.next = next;
return next; // 支持链式构建
}
public void handle(Request request) {
if (doHandle(request) && next != null) {
next.handle(request); // 当前处理通过,传递给下一个
}
}
protected abstract boolean doHandle(Request request);
}
// 参数校验
public class ParamValidationHandler extends Handler {
@Override
protected boolean doHandle(Request request) {
if (request.getParams() == null) {
throw new IllegalArgumentException("参数不能为空");
}
return true; // 通过,继续下一个
}
}
// 权限校验
public class AuthHandler extends Handler {
@Override
protected boolean doHandle(Request request) {
if (!request.isAuthenticated()) {
throw new SecurityException("未认证");
}
return true;
}
}
// 限流
public class RateLimitHandler extends Handler {
@Override
protected boolean doHandle(Request request) {
if (isRateLimited(request)) {
throw new RuntimeException("请求过于频繁");
}
return true;
}
}
// 组装责任链
Handler chain = new ParamValidationHandler();
chain.setNext(new AuthHandler())
.setNext(new RateLimitHandler());
chain.handle(request); // 依次经过:参数校验 → 权限 → 限流
Java/Spring 中的典型应用
| 应用 | 说明 |
|---|---|
| Servlet Filter | 多个 Filter 组成过滤器链 |
| Spring Interceptor | HandlerInterceptor 拦截器链 |
| Spring Security FilterChain | 安全过滤链(认证、授权、CSRF...) |
| Netty ChannelPipeline | 入站/出站处理器链 |
| Sentinel Slot | 限流验证的 ProcessorSlotChain |
java.util.logging.Logger | 日志处理链 |
Servlet Filter 链
@Component
@Order(1) // 顺序
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
long start = System.currentTimeMillis();
chain.doFilter(req, resp); // 传递给下一个 Filter
long cost = System.currentTimeMillis() - start;
log.info("请求耗时: {}ms", cost);
}
}
Spring Interceptor
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp,
Object handler) {
String token = req.getHeader("Authorization");
if (token == null) {
resp.setStatus(401);
return false; // 拦截,不继续往下
}
return true; // 放行
}
}
Filter vs Interceptor
| 维度 | Filter | Interceptor |
|---|---|---|
| 规范 | Servlet 规范 | Spring 框架 |
| 作用范围 | 所有请求(包括静态资源) | Controller 方法 |
| 注入 Spring Bean | 需要额外配置 | 天然支持 |
| 执行顺序 | Filter 包在 Interceptor 外层 |
常见面试问题
Q1: 责任链模式的优缺点?
答案:
优点:
- 解耦发送者和处理者
- 处理器可动态增删和排序
- 符合单一职责和开闭原则
缺点:
- 链太长影响性能
- 调试困难,不容易追踪请求经过了哪些处理器
Q2: Spring Security 的过滤器链有哪些关键 Filter?
答案:
关键 Filter 按顺序:
SecurityContextPersistenceFilter— 恢复 SecurityContextUsernamePasswordAuthenticationFilter— 处理表单登录BearerTokenAuthenticationFilter— 处理 JWTExceptionTranslationFilter— 异常处理FilterSecurityInterceptor— 权限校验
详见 微服务安全。