欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > Java设计模式之责任链模式:从入门到架构级实践

Java设计模式之责任链模式:从入门到架构级实践

2025/4/19 14:47:23 来源:https://blog.csdn.net/qq_42287536/article/details/147119630  浏览:    关键词:Java设计模式之责任链模式:从入门到架构级实践
1. 责任链模式简介

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,允许将请求沿着处理链传递,直到某个处理对象能够处理它。这种模式通过解耦请求的发送者和接收者,提供动态扩展处理逻辑的能力。责任链模式广泛应用于日志处理、权限校验、过滤器链(如Servlet Filter)、工作流审批等场景。

2. 责任链模式核心思想
  • 处理对象独立:每个处理节点(Handler)只关注自己的处理逻辑,无需知道链的结构。

  • 链式传递:若当前节点无法处理请求,则传递给下一个节点。

  • 动态配置:链的节点顺序和组合可以在运行时动态调整。


一、入门篇:基础实现与核心机制

1. 场景示例:请假审批流程

假设公司请假审批流程为:员工提交请假申请,需依次经过 主管 → 经理 → 总经理 三级审批,天数限制分别为3天、7天和无限。

2. 传统实现方式

(1)定义抽象处理者

public abstract class LeaveHandler {protected LeaveHandler nextHandler;// 设置下一个处理节点(链式调用支持)public LeaveHandler setNext(LeaveHandler next) {this.nextHandler = next;return next; // 支持链式调用:supervisor.setNext(manager).setNext(generalManager);}// 处理请求的抽象方法public abstract void handleRequest(LeaveRequest request);
}

(2)请求对象封装

public class LeaveRequest {private int days;private String reason;public LeaveRequest(int days) {this.days = days;}// getters & setters
}

(3)具体处理者实现

// 主管审批
public class SupervisorHandler extends LeaveHandler {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() <= 3) {System.out.println("[Supervisor] Approved: " + request.getDays() + " days");} else {System.out.println("[Supervisor] Forwarding to next handler...");if (nextHandler != null) {nextHandler.handleRequest(request);} else {System.out.println("No handler available to process this request!");}}}
}// 经理审批
public class ManagerHandler extends LeaveHandler {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() <= 7) {System.out.println("[Manager] Approved: " + request.getDays() + " days");} else {System.out.println("[Manager] Forwarding to next handler...");if (nextHandler != null) {nextHandler.handleRequest(request);}}}
}// 总经理审批(终结节点)
public class GeneralManagerHandler extends LeaveHandler {@Overridepublic void handleRequest(LeaveRequest request) {System.out.println("[General Manager] Approved: " + request.getDays() + " days");}
}

(4)客户端调用与链式构建

public class Client {public static void main(String[] args) {// 构建责任链(链式调用)LeaveHandler supervisor = new SupervisorHandler();supervisor.setNext(new ManagerHandler()).setNext(new GeneralManagerHandler());// 提交请求LeaveRequest request1 = new LeaveRequest(2);supervisor.handleRequest(request1);  // Supervisor审批LeaveRequest request2 = new LeaveRequest(5);supervisor.handleRequest(request2);  // Manager审批LeaveRequest request3 = new LeaveRequest(10);supervisor.handleRequest(request3);  // General Manager审批}
}

3. 责任链模式的关键问题
  • 终止条件:若不设计终止节点,可能导致请求未被处理。

  • 性能权衡:链的长度影响处理效率,需避免过长链。

  • 请求状态管理:是否允许修改请求对象?是否需要传递额外上下文?


二、进阶篇:动态配置与框架集成

1. 动态配置责任链

实际项目中,处理链的节点可能需要通过配置文件或数据库动态加载。

(1)配置文件定义节点顺序

# handler-chain.properties
handler.order=supervisor,manager,generalManager
handler.supervisor.class=com.example.SupervisorHandler
handler.manager.class=com.example.ManagerHandler
handler.generalManager.class=com.example.GeneralManagerHandler

(2)工厂类反射构建链

public class HandlerChainFactory {public static LeaveHandler createChain() throws Exception {Properties props = new Properties();props.load(HandlerChainFactory.class.getResourceAsStream("/handler-chain.properties"));String[] handlerOrder = props.getProperty("handler.order").split(",");LeaveHandler first = null, current = null;for (String key : handlerOrder) {String className = props.getProperty("handler." + key + ".class");Class<?> clazz = Class.forName(className);LeaveHandler handler = (LeaveHandler) clazz.getDeclaredConstructor().newInstance();if (first == null) {first = current = handler;} else {current.setNext(handler);current = handler;}}return first;}
}
2. 结合Spring框架的依赖注入

在Spring应用中,可通过@Order注解和List注入实现自动排序。

(1)定义处理接口与上下文对象

public interface RequestHandler {boolean handle(RequestContext context);
}public class RequestContext {private boolean handled = false;private Map<String, Object> attributes = new HashMap<>();// 添加属性(用于跨处理器传递数据)public void setAttribute(String key, Object value) {attributes.put(key, value);}public Object getAttribute(String key) {return attributes.get(key);}public void markHandled() {this.handled = true;}public boolean isHandled() {return handled;}
}

(2)Spring Bean处理器实现

@Component
@Order(1)
public class ValidationHandler implements RequestHandler {@Overridepublic boolean handle(RequestContext context) {System.out.println("Validating request...");if (context.getAttribute("data") == null) {throw new IllegalArgumentException("Invalid request data");}return false; // 未完全处理,继续传递}
}@Component
@Order(2)
public class BusinessLogicHandler implements RequestHandler {@Overridepublic boolean handle(RequestContext context) {System.out.println("Processing business logic...");context.markHandled(); // 标记为已处理return true; // 终止链}
}

(3)链执行器

@Component
public class HandlerChainExecutor {private final List<RequestHandler> handlers;@Autowiredpublic HandlerChainExecutor(List<RequestHandler> handlers) {this.handlers = handlers.stream().sorted(AnnotationAwareOrderComparator.INSTANCE).collect(Collectors.toList());}public void execute(RequestContext context) {for (RequestHandler handler : handlers) {if (handler.handle(context) || context.isHandled()) {break; // 终止链}}}
}

三、架构实践:高级应用与性能优化

1. 结合AOP实现横切关注点

通过责任链模式统一处理日志、权限校验等横切逻辑。

(1)定义切面链

public abstract class AbstractAspectHandler {private AbstractAspectHandler next;public void setNext(AbstractAspectHandler next) {this.next = next;}public void handle(ProceedingJoinPoint joinPoint) throws Throwable {if (canHandle(joinPoint)) {doHandle(joinPoint);}if (next != null) {next.handle(joinPoint);}}protected abstract boolean canHandle(ProceedingJoinPoint joinPoint);protected abstract void doHandle(ProceedingJoinPoint joinPoint) throws Throwable;
}// 具体实现:权限校验
public class AuthHandler extends AbstractAspectHandler {@Overrideprotected boolean canHandle(ProceedingJoinPoint joinPoint) {return true; // 所有方法都需要鉴权}@Overrideprotected void doHandle(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Auth check...");// 若鉴权失败,抛出异常}
}// 具体实现:日志记录
public class LogHandler extends AbstractAspectHandler {@Overrideprotected boolean canHandle(ProceedingJoinPoint joinPoint) {return true;}@Overrideprotected void doHandle(ProceedingJoinPoint joinPoint) {System.out.println("Logging method call: " + joinPoint.getSignature());}
}
2. 在微服务网关中的应用

Spring Cloud Gateway的过滤器链是责任链模式的典型应用。

(1)自定义网关过滤器

@Component
public class RateLimitFilter implements GatewayFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {if (exceedsRateLimit(exchange)) {exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);return exchange.getResponse().setComplete();}return chain.filter(exchange);}private boolean exceedsRateLimit(ServerWebExchange exchange) {// 实现限流逻辑return false;}
}// 全局过滤器
@Component
public class LoggingFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {System.out.println("Request path: " + exchange.getRequest().getPath());return chain.filter(exchange);}
}

(2)过滤器配置

spring:cloud:gateway:routes:- id: service_routeuri: http://localhost:8080predicates:- Path=/service/**filters:- RateLimitFilter- RewritePath=/service/(?<segment>.*), /$\{segment}
3. 性能优化策略
  • 短路机制:某些处理器可中断链(如权限校验失败)。

  • 异步处理:将非关键处理器改为异步执行(如日志记录)。

  • 缓存处理器:对无状态处理器实例进行复用。

  • 并行处理:使用CompletableFuture并行执行独立处理器。

public class ParallelHandlerChain {private List<LeaveHandler> handlers = new ArrayList<>();public void addHandler(LeaveHandler handler) {handlers.add(handler);}public void handleRequest(LeaveRequest request) {handlers.parallelStream().filter(handler -> handler.canHandle(request)).findFirst().ifPresent(handler -> handler.handle(request));}
}

四、模式变体与扩展

1. 功能式责任链(Java 8+)

利用Lambda和函数式接口简化代码:

public class FunctionalChain {private List<Predicate<Request>> validators = new ArrayList<>();private List<Consumer<Request>> processors = new ArrayList<>();public FunctionalChain addValidator(Predicate<Request> validator) {validators.add(validator);return this;}public FunctionalChain addProcessor(Consumer<Request> processor) {processors.add(processor);return this;}public boolean execute(Request request) {boolean isValid = validators.stream().allMatch(validator -> validator.test(request));if (isValid) {processors.forEach(processor -> processor.accept(request));return true;}return false;}
}// 使用示例
new FunctionalChain().addValidator(req -> req.getUserId() != null).addValidator(req -> req.getAmount() > 0).addProcessor(req -> System.out.println("Processing: " + req)).execute(request);
2. 责任链与模板方法结合

在抽象类中定义处理流程骨架:

public abstract class TemplateHandler {private TemplateHandler next;public final void handle(Request request) {if (canHandle(request)) {doHandle(request);} else {passToNext(request);}}protected abstract boolean canHandle(Request request);protected abstract void doHandle(Request request);protected void passToNext(Request request) {if (next != null) {next.handle(request);} else {throw new IllegalStateException("No handler available for request: " + request);}}
}

五、总结与最佳实践

1. 责任链模式适用场景
  • 多级审批流程:如请假、报销审批。

  • 可插拔处理逻辑:如HTTP请求处理管道。

  • 横切关注点分离:如日志、安全、事务管理。

2. 反模式与注意事项
  • 避免循环依赖:处理器之间不应形成循环引用。

  • 明确终止条件:防止请求未被处理导致内存泄漏。

  • 控制链的长度:过长的链会增加调试难度。

3. 调试技巧
  • 唯一标识:为每个处理器添加ID,便于日志追踪。

  • 链可视化:实现toString()方法输出链结构。

public class SupervisorHandler extends LeaveHandler {@Overridepublic String toString() {return "SupervisorHandler -> " + (nextHandler != null ? nextHandler.toString() : "null");}
}
4. 扩展方向
  • 与观察者模式结合:处理器处理完成后发布事件。

  • 分布式责任链:通过消息队列将处理器分布在多个服务中。

  • 配置中心集成:动态更新处理链配置(如Apollo、Nacos)。


通过深入理解责任链模式的核心机制,并结合实际业务需求灵活扩展,开发者可以构建出高内聚、低耦合、易维护的处理流程,有效应对复杂业务场景的挑战。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词