设计模式-12责任链模式Chain of Responsibility Pattern
责任链模式是一种行为设计模式,允许多个对象处理请求,避免请求发送者与接收者直接耦合。它将对象连成链,请求沿链传递直至被处理。适用于需要动态指定处理顺序、避免直接耦合的场景。结构包含处理者接口、抽象处理者和具体处理者。实现时,每个处理者决定是否能处理请求或传递给下一处理者。示例展示了采购审批流程,不同级别审批人根据金额限制处理请求,无法处理则转交上级。
责任链模式 (Chain of Responsibility Pattern)
概述 (Overview)
责任链模式是一种行为型设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
Chain of Responsibility Pattern is a behavioral design pattern that allows multiple objects to handle a request, avoiding coupling between the sender and receiver of the request. These objects are linked into a chain, and the request is passed along the chain until an object handles it.
意图 (Intent)
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
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.
适用场景 (When to Use)
- 当需要让多个对象都有机会处理请求时
- 当需要动态指定处理请求的对象集合时
- 当请求的处理者不明确或需要动态确定时
- 当需要避免请求发送者和接收者之间的直接耦合时
- 当需要按照特定顺序处理请求时
结构 (Structure)
基础责任链模式结构图 (Basic Chain of Responsibility Pattern Structure)
实现方式 (Implementation Approaches)
1. 经典责任链模式 (Classic Chain of Responsibility Pattern)
// 请求类 - Request Class
public class PurchaseRequest {
private int number;
private double amount;
private String purpose;
public PurchaseRequest(int number, double amount, String purpose) {
this.number = number;
this.amount = amount;
this.purpose = purpose;
}
public int getNumber() { return number; }
public double getAmount() { return amount; }
public String getPurpose() { return purpose; }
}
// 处理者接口 - Handler Interface
public interface Approver {
void setNext(Approver next);
void processRequest(PurchaseRequest request);
}
// 抽象处理者 - Abstract Handler
public abstract class AbstractApprover implements Approver {
protected Approver nextApprover;
protected String name;
protected double approvalLimit;
public AbstractApprover(String name, double approvalLimit) {
this.name = name;
this.approvalLimit = approvalLimit;
}
@Override
public void setNext(Approver next) {
this.nextApprover = next;
}
@Override
public void processRequest(PurchaseRequest request) {
if (canApprove(request)) {
approve(request);
} else if (nextApprover != null) {
System.out.println(name + " 无法处理,转交给上级");
nextApprover.processRequest(request);
} else {
System.out.println(name + " 无法处理,且没有上级可以转交");
}
}
protected boolean canApprove(PurchaseRequest request) {
return request.getAmount() <= approvalLimit;
}
protected abstract void approve(PurchaseRequest request);
}
// 具体处理者 - Concrete Handlers
public class Manager extends AbstractApprover {
public Manager(String name) {
super(name, 10000);
}
@Override
protected void approve(PurchaseRequest request) {
System.out.println(name + " (经理) 批准了采购申请 #" + request.getNumber() +
",金额: ¥" + request.getAmount() + ",用途: " + request.getPurpose());
}
}
public class Director extends AbstractApprover {
public Director(String name) {
super(name, 50000);
}
@Override
protected void approve(PurchaseRequest request) {
System.out.println(name + " (总监) 批准了采购申请 #" + request.getNumber() +
",金额: ¥" + request.getAmount() + ",用途: " + request.getPurpose());
}
}
public class CEO extends AbstractApprover {
public CEO(String name) {
super(name, 100000);
}
@Override
protected void approve(PurchaseRequest request) {
System.out.println(name + " (CEO) 批准了采购申请 #" + request.getNumber() +
",金额: ¥" + request.getAmount() + ",用途: " + request.getPurpose());
}
}
public class Board extends AbstractApprover {
public Board(String name) {
super(name, Double.MAX_VALUE);
}
@Override
protected void approve(PurchaseRequest request) {
System.out.println(name + " (董事会) 批准了采购申请 #" + request.getNumber() +
",金额: ¥" + request.getAmount() + ",用途: " + request.getPurpose());
}
}
// 客户端使用 - Client Usage
public class PurchaseApprovalSystem {
public static void main(String[] args) {
System.out.println("=== 采购审批责任链模式演示 ===");
// 创建处理者
Approver manager = new Manager("王经理");
Approver director = new Director("李总监");
Approver ceo = new CEO("张CEO");
Approver board = new Board("董事会");
// 构建责任链
manager.setNext(director);
director.setNext(ceo);
ceo.setNext(board);
// 创建采购申请
PurchaseRequest[] requests = {
new PurchaseRequest(1, 5000, "办公用品"),
new PurchaseRequest(2, 20000, "电脑设备"),
new PurchaseRequest(3, 80000, "服务器"),
new PurchaseRequest(4, 150000, "新办公楼"),
new PurchaseRequest(5, 300000, "公司收购")
};
// 处理申请
for (PurchaseRequest request : requests) {
System.out.println("\n处理采购申请 #" + request.getNumber() +
",金额: ¥" + request.getAmount());
manager.processRequest(request);
}
}
}
2. 日志处理责任链模式 (Logging Chain of Responsibility Pattern)
// 日志级别枚举 - Log Level Enum
public enum LogLevel {
DEBUG(1), INFO(2), WARN(3), ERROR(4), FATAL(5);
private int level;
LogLevel(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
}
// 日志消息类 - Log Message Class
public class LogMessage {
private LogLevel level;
private String message;
private String timestamp;
public LogMessage(LogLevel level, String message) {
this.level = level;
this.message = message;
this.timestamp = new Date().toString();
}
public LogLevel getLevel() { return level; }
public String getMessage() { return message; }
public String getTimestamp() { return timestamp; }
}
// 日志处理器接口 - Log Handler Interface
public interface LogHandler {
void setNext(LogHandler next);
void handleLog(LogMessage message);
}
// 抽象日志处理器 - Abstract Log Handler
public abstract class AbstractLogHandler implements LogHandler {
protected LogHandler nextHandler;
protected LogLevel minLevel;
protected String handlerName;
public AbstractLogHandler(String handlerName, LogLevel minLevel) {
this.handlerName = handlerName;
this.minLevel = minLevel;
}
@Override
public void setNext(LogHandler next) {
this.nextHandler = next;
}
@Override
public void handleLog(LogMessage message) {
if (message.getLevel().getLevel() >= minLevel.getLevel()) {
writeLog(message);
}
if (nextHandler != null) {
nextHandler.handleLog(message);
}
}
protected abstract void writeLog(LogMessage message);
}
// 具体日志处理器 - Concrete Log Handlers
public class ConsoleLogHandler extends AbstractLogHandler {
public ConsoleLogHandler() {
super("控制台", LogLevel.DEBUG);
}
@Override
protected void writeLog(LogMessage message) {
System.out.println("[控制台][" + message.getLevel() + "] " +
message.getTimestamp() + " - " + message.getMessage());
}
}
public class FileLogHandler extends AbstractLogHandler {
private String fileName;
public FileLogHandler(String fileName) {
super("文件", LogLevel.INFO);
this.fileName = fileName;
}
@Override
protected void writeLog(LogMessage message) {
System.out.println("[文件][" + message.getLevel() + "] " + fileName + " - " +
message.getTimestamp() + " - " + message.getMessage());
// 实际应用中这里会写入文件
}
}
public class DatabaseLogHandler extends AbstractLogHandler {
public DatabaseLogHandler() {
super("数据库", LogLevel.WARN);
}
@Override
protected void writeLog(LogMessage message) {
System.out.println("[数据库][" + message.getLevel() + "] " +
message.getTimestamp() + " - " + message.getMessage());
// 实际应用中这里会写入数据库
}
}
public class EmailLogHandler extends AbstractLogHandler {
private String emailAddress;
public EmailLogHandler(String emailAddress) {
super("邮件", LogLevel.ERROR);
this.emailAddress = emailAddress;
}
@Override
protected void writeLog(LogMessage message) {
System.out.println("[邮件][" + message.getLevel() + "] 发送到 " + emailAddress + " - " +
message.getTimestamp() + " - " + message.getMessage());
// 实际应用中这里会发送邮件
}
}
// 日志管理器 - Log Manager
public class LogManager {
private LogHandler chain;
public LogManager() {
buildChain();
}
private void buildChain() {
// 创建处理器
ConsoleLogHandler consoleHandler = new ConsoleLogHandler();
FileLogHandler fileHandler = new FileLogHandler("application.log");
DatabaseLogHandler dbHandler = new DatabaseLogHandler();
EmailLogHandler emailHandler = new EmailLogHandler("admin@company.com");
// 构建责任链
consoleHandler.setNext(fileHandler);
fileHandler.setNext(dbHandler);
dbHandler.setNext(emailHandler);
chain = consoleHandler;
}
public void log(LogLevel level, String message) {
LogMessage logMessage = new LogMessage(level, message);
chain.handleLog(logMessage);
}
public void debug(String message) {
log(LogLevel.DEBUG, message);
}
public void info(String message) {
log(LogLevel.INFO, message);
}
public void warn(String message) {
log(LogLevel.WARN, message);
}
public void error(String message) {
log(LogLevel.ERROR, message);
}
public void fatal(String message) {
log(LogLevel.FATAL, message);
}
}
// 客户端使用 - Client Usage
public class LoggingSystem {
public static void main(String[] args) {
System.out.println("=== 日志系统责任链模式演示 ===");
LogManager logManager = new LogManager();
// 测试不同级别的日志
System.out.println("\n--- 调试信息 ---");
logManager.debug("应用程序启动");
System.out.println("\n--- 普通信息 ---");
logManager.info("用户登录成功");
System.out.println("\n--- 警告信息 ---");
logManager.warn("内存使用率较高");
System.out.println("\n--- 错误信息 ---");
logManager.error("数据库连接失败");
System.out.println("\n--- 致命错误 ---");
logManager.fatal("系统崩溃,需要立即处理");
}
}
3. 异常处理责任链模式 (Exception Handling Chain of Responsibility Pattern)
// 异常类型枚举 - Exception Type Enum
public enum ExceptionType {
VALIDATION, BUSINESS, SYSTEM, SECURITY, NETWORK
}
// 异常信息类 - Exception Info Class
public class ExceptionInfo {
private ExceptionType type;
private String message;
private Throwable cause;
private String context;
public ExceptionInfo(ExceptionType type, String message, Throwable cause, String context) {
this.type = type;
this.message = message;
this.cause = cause;
this.context = context;
}
// Getters
public ExceptionType getType() { return type; }
public String getMessage() { return message; }
public Throwable getCause() { return cause; }
public String getContext() { return context; }
}
// 异常处理器接口 - Exception Handler Interface
public interface ExceptionHandler {
void setNext(ExceptionHandler next);
void handleException(ExceptionInfo exception);
}
// 抽象异常处理器 - Abstract Exception Handler
public abstract class AbstractExceptionHandler implements ExceptionHandler {
protected ExceptionHandler nextHandler;
protected List<ExceptionType> supportedTypes;
protected String handlerName;
public AbstractExceptionHandler(String handlerName, ExceptionType... supportedTypes) {
this.handlerName = handlerName;
this.supportedTypes = Arrays.asList(supportedTypes);
}
@Override
public void setNext(ExceptionHandler next) {
this.nextHandler = next;
}
@Override
public void handleException(ExceptionInfo exception) {
if (canHandle(exception)) {
handle(exception);
}
if (nextHandler != null) {
nextHandler.handleException(exception);
}
}
protected boolean canHandle(ExceptionInfo exception) {
return supportedTypes.contains(exception.getType());
}
protected abstract void handle(ExceptionInfo exception);
}
// 具体异常处理器 - Concrete Exception Handlers
public class ValidationExceptionHandler extends AbstractExceptionHandler {
public ValidationExceptionHandler() {
super("验证异常处理器", ExceptionType.VALIDATION);
}
@Override
protected void handle(ExceptionInfo exception) {
System.out.println("[" + handlerName + "] 处理验证异常:");
System.out.println(" - 错误信息: " + exception.getMessage());
System.out.println(" - 错误上下文: " + exception.getContext());
System.out.println(" - 处理建议: 检查输入参数,确保数据格式正确");
System.out.println(" - 返回友好的错误提示给用户");
}
}
public class BusinessExceptionHandler extends AbstractExceptionHandler {
public BusinessExceptionHandler() {
super("业务异常处理器", ExceptionType.BUSINESS);
}
@Override
protected void handle(ExceptionInfo exception) {
System.out.println("[" + handlerName + "] 处理业务异常:");
System.out.println(" - 错误信息: " + exception.getMessage());
System.out.println(" - 错误上下文: " + exception.getContext());
System.out.println(" - 处理建议: 检查业务逻辑,确认操作是否符合业务规则");
System.out.println(" - 记录业务日志,通知相关业务人员");
}
}
public class SystemExceptionHandler extends AbstractExceptionHandler {
public SystemExceptionHandler() {
super("系统异常处理器", ExceptionType.SYSTEM);
}
@Override
protected void handle(ExceptionInfo exception) {
System.out.println("[" + handlerName + "] 处理系统异常:");
System.out.println(" - 错误信息: " + exception.getMessage());
System.out.println(" - 错误上下文: " + exception.getContext());
if (exception.getCause() != null) {
System.out.println(" - 异常原因: " + exception.getCause().getMessage());
}
System.out.println(" - 处理建议: 检查系统资源,查看系统日志");
System.out.println(" - 发送系统告警,可能需要技术团队介入");
}
}
public class SecurityExceptionHandler extends AbstractExceptionHandler {
public SecurityExceptionHandler() {
super("安全异常处理器", ExceptionType.SECURITY);
}
@Override
protected void handle(ExceptionInfo exception) {
System.out.println("[" + handlerName + "] 处理安全异常:");
System.out.println(" - 错误信息: " + exception.getMessage());
System.out.println(" - 错误上下文: " + exception.getContext());
System.out.println(" - 处理建议: 检查用户权限,验证访问令牌");
System.out.println(" - 记录安全日志,可能需要安全团队调查");
System.out.println(" - 考虑锁定相关账户或IP地址");
}
}
public class NetworkExceptionHandler extends AbstractExceptionHandler {
public NetworkExceptionHandler() {
super("网络异常处理器", ExceptionType.NETWORK);
}
@Override
protected void handle(ExceptionInfo exception) {
System.out.println("[" + handlerName + "] 处理网络异常:");
System.out.println(" - 错误信息: " + exception.getMessage());
System.out.println(" - 错误上下文: " + exception.getContext());
System.out.println(" - 处理建议: 检查网络连接,重试操作");
System.out.println(" - 实施熔断机制,避免级联故障");
System.out.println(" - 记录网络状态,监控网络性能");
}
}
// 异常处理管理器 - Exception Handling Manager
public class ExceptionHandlingManager {
private ExceptionHandler chain;
public ExceptionHandlingManager() {
buildChain();
}
private void buildChain() {
// 创建处理器
ValidationExceptionHandler validationHandler = new ValidationExceptionHandler();
BusinessExceptionHandler businessHandler = new BusinessExceptionHandler();
SystemExceptionHandler systemHandler = new SystemExceptionHandler();
SecurityExceptionHandler securityHandler = new SecurityExceptionHandler();
NetworkExceptionHandler networkHandler = new NetworkExceptionHandler();
// 构建责任链(按照优先级顺序)
validationHandler.setNext(businessHandler);
businessHandler.setNext(systemHandler);
systemHandler.setNext(securityHandler);
securityHandler.setNext(networkHandler);
chain = validationHandler;
}
public void handleException(ExceptionType type, String message, Throwable cause, String context) {
ExceptionInfo exceptionInfo = new ExceptionInfo(type, message, cause, context);
chain.handleException(exceptionInfo);
}
public void handleException(ExceptionType type, String message, String context) {
handleException(type, message, null, context);
}
public void handleException(Exception e, String context) {
ExceptionType type = classifyException(e);
handleException(type, e.getMessage(), e, context);
}
private ExceptionType classifyException(Throwable e) {
if (e instanceof IllegalArgumentException || e instanceof ValidationException) {
return ExceptionType.VALIDATION;
} else if (e instanceof BusinessException) {
return ExceptionType.BUSINESS;
} else if (e instanceof SecurityException) {
return ExceptionType.SECURITY;
} else if (e instanceof ConnectException || e instanceof SocketException) {
return ExceptionType.NETWORK;
} else {
return ExceptionType.SYSTEM;
}
}
}
// 自定义异常类 - Custom Exception Classes
class ValidationException extends RuntimeException {
public ValidationException(String message) {
super(message);
}
}
class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
}
// 客户端使用 - Client Usage
public class ExceptionHandlingSystem {
public static void main(String[] args) {
System.out.println("=== 异常处理责任链模式演示 ===");
ExceptionHandlingManager exceptionManager = new ExceptionHandlingManager();
// 模拟不同类型的异常
System.out.println("\n--- 验证异常 ---");
exceptionManager.handleException(
ExceptionType.VALIDATION,
"用户名不能为空",
"用户注册功能"
);
System.out.println("\n--- 业务异常 ---");
exceptionManager.handleException(
ExceptionType.BUSINESS,
"账户余额不足",
"转账操作"
);
System.out.println("\n--- 系统异常 ---");
exceptionManager.handleException(
ExceptionType.SYSTEM,
"数据库连接超时",
new SQLException("Connection timeout"),
"数据查询"
);
System.out.println("\n--- 安全异常 ---");
exceptionManager.handleException(
ExceptionType.SECURITY,
"无效的访问令牌",
"API访问"
);
System.out.println("\n--- 网络异常 ---");
exceptionManager.handleException(
ExceptionType.NETWORK,
"无法连接到远程服务",
"微服务调用"
);
// 模拟实际异常处理
System.out.println("\n--- 实际异常处理演示 ---");
try {
validateUserInput("");
} catch (Exception e) {
exceptionManager.handleException(e, "用户输入验证");
}
try {
processBusinessLogic(-100);
} catch (Exception e) {
exceptionManager.handleException(e, "业务逻辑处理");
}
}
private static void validateUserInput(String input) {
if (input == null || input.trim().isEmpty()) {
throw new ValidationException("用户输入不能为空");
}
}
private static void processBusinessLogic(int amount) {
if (amount < 0) {
throw new BusinessException("交易金额不能为负数");
}
}
}
框架源码中的应用 (Framework Applications)
1. Java Servlet - Filter链
// Java Servlet中的Filter链责任链模式应用
// Java Servlet Filter Chain Responsibility Pattern Application
// 自定义过滤器 - Custom Filter
public class AuthenticationFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("认证过滤器初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("认证过滤器开始处理");
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 模拟认证逻辑
String authHeader = httpRequest.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
System.out.println("认证失败:缺少有效的认证信息");
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpResponse.getWriter().write("认证失败:需要有效的访问令牌");
return;
}
System.out.println("认证成功,继续处理链");
chain.doFilter(request, response);
System.out.println("认证过滤器处理完成");
}
@Override
public void destroy() {
System.out.println("认证过滤器销毁");
}
}
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("日志过滤器初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
long startTime = System.currentTimeMillis();
System.out.println("日志过滤器开始处理");
HttpServletRequest httpRequest = (HttpServletRequest) request;
System.out.println("请求URL: " + httpRequest.getRequestURL());
System.out.println("请求方法: " + httpRequest.getMethod());
// 继续处理链
chain.doFilter(request, response);
long endTime = System.currentTimeMillis();
System.out.println("请求处理时间: " + (endTime - startTime) + "ms");
System.out.println("日志过滤器处理完成");
}
@Override
public void destroy() {
System.out.println("日志过滤器销毁");
}
}
public class CompressionFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("压缩过滤器初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("压缩过滤器开始处理");
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 包装响应以支持压缩
CompressionResponseWrapper compressedResponse =
new CompressionResponseWrapper(httpResponse);
System.out.println("启用响应压缩");
chain.doFilter(request, compressedResponse);
// 完成压缩
compressedResponse.finishResponse();
System.out.println("压缩过滤器处理完成");
}
@Override
public void destroy() {
System.out.println("压缩过滤器销毁");
}
}
// 压缩响应包装器 - Compression Response Wrapper
public class CompressionResponseWrapper extends HttpServletResponseWrapper {
private GZIPServletOutputStream gzipOutputStream;
private PrintWriter printWriter;
public CompressionResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (printWriter != null) {
throw new IllegalStateException("getWriter() has already been called");
}
if (gzipOutputStream == null) {
gzipOutputStream = new GZIPServletOutputStream(getResponse().getOutputStream());
}
return gzipOutputStream;
}
@Override
public PrintWriter getWriter() throws IOException {
if (gzipOutputStream != null) {
throw new IllegalStateException("getOutputStream() has already been called");
}
if (printWriter == null) {
gzipOutputStream = new GZIPServletOutputStream(getResponse().getOutputStream());
printWriter = new PrintWriter(new OutputStreamWriter(gzipOutputStream, getCharacterEncoding()));
}
return printWriter;
}
public void finishResponse() throws IOException {
if (gzipOutputStream != null) {
gzipOutputStream.finish();
}
if (printWriter != null) {
printWriter.close();
}
}
}
// GZIP Servlet输出流 - GZIP Servlet Output Stream
public class GZIPServletOutputStream extends ServletOutputStream {
private GZIPOutputStream gzipOutputStream;
public GZIPServletOutputStream(ServletOutputStream outputStream) throws IOException {
this.gzipOutputStream = new GZIPOutputStream(outputStream);
}
@Override
public void write(int b) throws IOException {
gzipOutputStream.write(b);
}
@Override
public void flush() throws IOException {
gzipOutputStream.flush();
}
@Override
public void close() throws IOException {
gzipOutputStream.close();
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
// 实现写入监听器
}
public void finish() throws IOException {
gzipOutputStream.finish();
}
}
// Spring Boot配置 - Spring Boot Configuration
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<AuthenticationFilter> authenticationFilter() {
FilterRegistrationBean<AuthenticationFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new AuthenticationFilter());
registrationBean.addUrlPatterns("/api/*");
registrationBean.setOrder(1); // 最高优先级
return registrationBean;
}
@Bean
public FilterRegistrationBean<LoggingFilter> loggingFilter() {
FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new LoggingFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(2);
return registrationBean;
}
@Bean
public FilterRegistrationBean<CompressionFilter> compressionFilter() {
FilterRegistrationBean<CompressionFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CompressionFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(3);
return registrationBean;
}
}
// 测试控制器 - Test Controller
@RestController
@RequestMapping("/api")
public class TestController {
@GetMapping("/test")
public ResponseEntity<String> testEndpoint() {
System.out.println("控制器处理请求");
return ResponseEntity.ok("请求处理成功");
}
}
// 客户端使用 - Client Usage
@SpringBootApplication
public class ServletFilterDemo {
public static void main(String[] args) {
SpringApplication.run(ServletFilterDemo.class, args);
System.out.println("=== Servlet Filter链责任链模式演示 ===");
System.out.println("启动Spring Boot应用,访问 http://localhost:8080/api/test");
System.out.println("观察控制台输出,可以看到Filter链的执行顺序");
}
}
2. Spring Security - 过滤器链
// Spring Security中的过滤器链责任链模式应用
// Spring Security Filter Chain Responsibility Pattern Application
// 自定义安全过滤器 - Custom Security Filter
public class CustomAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
System.out.println("自定义认证过滤器开始处理");
// 模拟认证逻辑
String token = extractToken(request);
if (token != null && validateToken(token)) {
System.out.println("Token验证成功: " + token);
// 设置认证信息
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken("user", null, getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
System.out.println("Token验证失败或不存在");
}
// 继续过滤器链
filterChain.doFilter(request, response);
System.out.println("自定义认证过滤器处理完成");
}
private String extractToken(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
private boolean validateToken(String token) {
// 简单的Token验证逻辑
return token.length() > 10;
}
private Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
}
}
// 自定义授权过滤器 - Custom Authorization Filter
public class CustomAuthorizationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
System.out.println("自定义授权过滤器开始处理");
// 获取当前认证信息
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
System.out.println("用户已认证: " + authentication.getName());
System.out.println("用户权限: " + authentication.getAuthorities());
// 检查特定权限
if (requiresAdmin(request) && !hasAdminRole(authentication)) {
System.out.println("需要管理员权限,但当前用户没有");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write("需要管理员权限");
return;
}
} else {
System.out.println("用户未认证");
}
// 继续过滤器链
filterChain.doFilter(request, response);
System.out.println("自定义授权过滤器处理完成");
}
private boolean requiresAdmin(HttpServletRequest request) {
return request.getRequestURI().contains("/admin");
}
private boolean hasAdminRole(Authentication authentication) {
return authentication.getAuthorities().stream()
.anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"));
}
}
// 请求日志过滤器 - Request Logging Filter
public class RequestLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
long startTime = System.currentTimeMillis();
System.out.println("请求日志过滤器开始处理");
System.out.println("请求URI: " + request.getRequestURI());
System.out.println("请求方法: " + request.getMethod());
System.out.println("远程地址: " + request.getRemoteAddr());
// 继续过滤器链
filterChain.doFilter(request, response);
long endTime = System.currentTimeMillis();
System.out.println("响应状态: " + response.getStatus());
System.out.println("请求处理时间: " + (endTime - startTime) + "ms");
System.out.println("请求日志过滤器处理完成");
}
}
// Spring Security配置 - Spring Security Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilterBefore(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new CustomAuthorizationFilter(), FilterSecurityInterceptor.class)
.addFilterBefore(new RequestLoggingFilter(), CustomAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER")
.and()
.withUser("admin").password("{noop}admin").roles("ADMIN");
}
}
// 测试控制器 - Test Controller
@RestController
@RequestMapping("/api")
public class SecurityTestController {
@GetMapping("/public/test")
public ResponseEntity<String> publicEndpoint() {
return ResponseEntity.ok("公共接口访问成功");
}
@GetMapping("/admin/test")
public ResponseEntity<String> adminEndpoint() {
return ResponseEntity.ok("管理员接口访问成功");
}
@GetMapping("/user/test")
public ResponseEntity<String> userEndpoint() {
return ResponseEntity.ok("用户接口访问成功");
}
}
// 客户端使用 - Client Usage
@SpringBootApplication
@EnableWebSecurity
public class SpringSecurityFilterDemo {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityFilterDemo.class, args);
System.out.println("=== Spring Security过滤器链责任链模式演示 ===");
System.out.println("启动Spring Boot应用,测试不同的安全场景:");
System.out.println("1. 访问公共接口: curl http://localhost:8080/api/public/test");
System.out.println("2. 访问用户接口: curl -H 'Authorization: Bearer user_token123' http://localhost:8080/api/user/test");
System.out.println("3. 访问管理员接口: curl -H 'Authorization: Bearer admin_token123' http://localhost:8080/api/admin/test");
System.out.println("观察控制台输出,可以看到Spring Security过滤器链的执行顺序");
}
}
责任链模式与其他模式比较 (Comparison with Other Patterns)
特性 | 责任链模式 | 装饰器模式 | 策略模式 | 命令模式 |
---|---|---|---|---|
目的 | 请求传递处理 | 动态添加职责 | 算法选择 | 请求封装 |
结构 | 链式结构 | 链式结构 | 平行结构 | 队列结构 |
关注点 | 请求处理者 | 功能增强 | 算法变化 | 请求封装 |
使用场景 | 多级处理 | 功能扩展 | 算法替换 | 请求排队 |
控制方式 | 链式传递 | 链式调用 | 策略选择 | 命令执行 |
最佳实践 (Best Practices)
1. 链的构建 (Chain Construction)
- 明确责任链的顺序和优先级
- 考虑使用建造者模式构建复杂的责任链
- 确保链的末尾有适当的处理机制
2. 请求处理 (Request Handling)
- 明确定义请求的传递规则
- 考虑请求的终止条件
- 处理好请求的边界情况
3. 性能优化 (Performance Optimization)
- 避免过长的责任链
- 考虑使用缓存机制
- 合理设置超时机制
4. 错误处理 (Error Handling)
- 确保异常能够被正确处理
- 提供适当的错误反馈机制
- 考虑失败重试策略
5. 可扩展性 (Extensibility)
- 设计易于扩展的处理器接口
- 支持动态添加和移除处理器
- 考虑使用配置文件管理责任链
优缺点 (Pros and Cons)
优点 (Advantages)
- 降低耦合:发送者和接收者解耦
- 灵活性:可以动态改变链中的成员
- 可扩展:易于添加新的处理者
- 职责清晰:每个处理者只负责自己的处理逻辑
- 可维护性:易于理解和维护处理流程
缺点 (Disadvantages)
- 性能问题:请求可能需要遍历整个链才能被处理
- 调试困难:链式结构使得调试变得复杂
- 设计复杂:需要仔细设计链的结构和处理逻辑
- 不确定性:无法保证请求一定会被处理
- 循环风险:如果链设计不当,可能导致循环调用
实际应用建议 (Practical Application Tips)
1. 链的长度控制
- 保持责任链的合理长度,避免过长的链影响性能
- 对于复杂的处理流程,考虑使用组合模式或状态模式
2. 处理策略设计
- 明确定义每个处理者的处理范围和条件
- 考虑使用策略模式来处理不同类型的请求
3. 异常处理机制
- 在链的末尾设置默认的处理机制
- 考虑使用观察者模式来通知请求处理结果
4. 性能优化
- 使用缓存来避免重复的处理判断
- 考虑使用异步处理来提高响应速度
5. 测试策略
- 单独测试每个处理者的逻辑
- 测试完整的责任链流程
- 考虑边界情况和异常情况
总结 (Summary)
责任链模式是一种强大的行为型设计模式,它通过将请求沿着处理者链传递,实现了请求发送者和接收者的解耦。这种模式在Java Web开发中广泛应用,如Servlet Filter链和Spring Security过滤器链。
在实际应用中,责任链模式特别适合以下场景:
- 多级审批流程
- 日志处理系统
- 异常处理机制
- 请求预处理和后处理
- 安全认证和授权
通过合理使用责任链模式,可以构建出灵活、可扩展的系统架构,提高代码的可维护性和可扩展性。
更多推荐
所有评论(0)