马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
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 {
- @Override
- public 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 {
- @Override
- public 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 {
- @Override
- public 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 {
- @Override
- public 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 {
- @Override
- public boolean handle(RequestContext context) {
- System.out.println("Processing business logic...");
- context.markHandled(); // 标记为已处理
- return true; // 终止链
- }
- }
复制代码 (3)链实行器
- @Component
- public class HandlerChainExecutor {
- private final List<RequestHandler> handlers;
- @Autowired
- public 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 {
- @Override
- protected boolean canHandle(ProceedingJoinPoint joinPoint) {
- return true; // 所有方法都需要鉴权
- }
- @Override
- protected void doHandle(ProceedingJoinPoint joinPoint) throws Throwable {
- System.out.println("Auth check...");
- // 若鉴权失败,抛出异常
- }
- }
- // 具体实现:日志记录
- public class LogHandler extends AbstractAspectHandler {
- @Override
- protected boolean canHandle(ProceedingJoinPoint joinPoint) {
- return true;
- }
- @Override
- protected void doHandle(ProceedingJoinPoint joinPoint) {
- System.out.println("Logging method call: " + joinPoint.getSignature());
- }
- }
复制代码 2. 在微服务网关中的应用
Spring Cloud Gateway的过滤器链是责任链模式的典型应用。
(1)自定义网关过滤器
- @Component
- public class RateLimitFilter implements GatewayFilter {
- @Override
- public 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 {
- @Override
- public 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_route
- uri: http://localhost:8080
- predicates:
- - 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 {
- @Override
- public String toString() {
- return "SupervisorHandler -> " + (nextHandler != null ? nextHandler.toString() : "null");
- }
- }
复制代码 4. 扩展方向
- 与观察者模式结合:处理器处理完成后发布变乱。
- 分布式责任链:通过消息队列将处理器分布在多个服务中。
- 设置中央集成:动态更新处理链设置(如Apollo、Nacos)。
通过深入理解责任链模式的核心机制,并结合实际业务需求灵活扩展,开发者可以构建出高内聚、低耦合、易维护的处理流程,有效应对复杂业务场景的挑战。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |