背景
最近在写公司业务代码的时候用到了责任链模式,借这个机会回顾下责任链设计模式。
什么是责任链模式
责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行发送。当一个请求到达链的起始端时,它会依次经过每个处理者,直到有一个处理者能够处理该请求或者到达链的末端。以下是责任链模式的一些关键信息:
组成部分
- 抽象处理者(Handler) :定义了一个处理请求的抽象方法,并持有一个指向下一个处理者的引用。
- 具体处理者(Concrete Handler) :实现了抽象处理者的处理方法,在方法中判断是否能够处理请求,如果可以则处理,否则将请求传递给下一个处理者。
- 客户端(Client) :创建处理者链,并向链的起始端发送请求。
示例代码
java
// 抽象处理者
abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(int request);
}
// 具体处理者1
class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("ConcreteHandler1 处理请求 " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者2
class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("ConcreteHandler2 处理请求 " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
handler1.setSuccessor(handler2);
int[] requests = {5, 12, 18, 25};
for (int request : requests) {
handler1.handleRequest(request);
}
}
}
责任链设计模式 - 图示
整个图示就类似一个链表
责任链设计模式 - 审批案例
java
// 定义处理者接口
abstract class Approver {
protected Approver nextApprover;
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
public abstract void approve(int days);
}
// 具体处理者:组长
class TeamLeader extends Approver {
@Override
public void approve(int days) {
if (days <= 1) {
System.out.println("组长批准了 " + days + " 天的请假申请。");
} else if (nextApprover != null) {
nextApprover.approve(days);
}
}
}
// 具体处理者:经理
class Manager extends Approver {
@Override
public void approve(int days) {
if (days <= 3) {
System.out.println("经理批准了 " + days + " 天的请假申请。");
} else if (nextApprover != null) {
nextApprover.approve(days);
}
}
}
// 具体处理者:总监
class Director extends Approver {
@Override
public void approve(int days) {
if (days <= 7) {
System.out.println("总监批准了 " + days + " 天的请假申请。");
} else {
System.out.println("请假天数超过 7 天,申请被拒绝。");
}
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
// 创建处理者
Approver teamLeader = new TeamLeader();
Approver manager = new Manager();
Approver director = new Director();
// 构建责任链
teamLeader.setNextApprover(manager);
manager.setNextApprover(director);
// 发送请求
teamLeader.approve(1);
teamLeader.approve(3);
teamLeader.approve(5);
teamLeader.approve(10);
}
}
运行结果:
这个案例还是挺简单的,接下来我们再看一个spring中拦截器的案例。
Spring 中的 Interceptor
代码
java
// 自定义拦截器 1
@Component
public class FirstInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("FirstInterceptor: preHandle");
// 返回false,不会走后面拦截器
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("FirstInterceptor: postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("FirstInterceptor: afterCompletion");
}
}
java
// 自定义拦截器 2
@Component
public class SecondInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("SecondInterceptor: preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("SecondInterceptor: postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("SecondInterceptor: afterCompletion");
}
}
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private FirstInterceptor firstInterceptor;
@Autowired
private SecondInterceptor secondInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// /** 表示拦截所有请求
registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
registry.addInterceptor(secondInterceptor).addPathPatterns("/**");
}
}
执行结果
Interceptor 结构
从上面的执行结果我们可以分析出,interceptor的责任链是双向的,顺序执行完再逆序执行,如下图所示结构
pre、post、aftercompletion
interceptor 责任链各个处理器是用List来接住的,所以方便的顺序执行和逆序执行。
HandlerExecutionChain 类
接下来再具体看看哪里调用的。
DispatcherServlet 类
DispatcherServlet中的doDispatcher方法
pre执行时机:
从这里我们可以看到,如果拦截器链里有一个pre方法返回false,那么后续的pre以及post和aftercompletion都不会再执行。
post执行时机:
aftercompletion执行时机:
如果报错了,那么会在catch里执行aftercompletion
所以总结下来拦截器链的pre,post,aftercompletion执行顺序是:
(1)责任链顺序执行pre,如果返回的都是true,继续下面步骤 (2)逆序执行post (3)逆序执行aftercompletion
总结
spring 中 interceptor 用的也是责任链模式,不过是更加复杂的责任链,依赖于List组成一个抽象的双向链表,这样方便对责任链进行顺序遍历和逆序遍历。
模仿拦截器中的责任链
代码
java
// 订单类(保持不变)
class Order {
private String orderId;
private double amount;
private int quantity;
public Order(String orderId, double amount, int quantity) {
this.orderId = orderId;
this.amount = amount;
this.quantity = quantity;
}
public String getOrderId() {
return orderId;
}
public double getAmount() {
return amount;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
// 处理器接口(移除setNextHandler)
interface OrderHandler {
boolean preHandle(Order order);
void postHandle(Order order);
void afterCompletion(Order order, Exception ex);
}
// 订单验证处理器
class OrderValidatorHandler implements OrderHandler {
@Override
public boolean preHandle(Order order) {
if (order.getAmount() <= 0 || order.getQuantity() <= 0) {
System.out.println("订单验证失败:订单金额或数量无效。");
return false;
}
System.out.println("订单验证通过。");
return true; // 继续执行下一个处理器
}
@Override
public void postHandle(Order order) {
System.out.println("订单验证处理器:postHandle 操作完成。");
}
@Override
public void afterCompletion(Order order, Exception ex) {
System.out.println("订单验证处理器:afterCompletion 操作完成,异常信息:" + (ex != null ? ex.getMessage() : "无"));
}
}
// 库存检查处理器
class InventoryCheckHandler implements OrderHandler {
private int stock = 10;
@Override
public boolean preHandle(Order order) {
if (order.getQuantity() > stock) {
System.out.println("库存检查失败:库存不足。");
return false;
}
System.out.println("库存检查通过。");
stock -= order.getQuantity();
return true;
}
@Override
public void postHandle(Order order) {
System.out.println("库存检查处理器:postHandle 操作完成。");
}
@Override
public void afterCompletion(Order order, Exception ex) {
System.out.println("库存检查处理器:afterCompletion 操作完成,异常信息:" + (ex != null ? ex.getMessage() : "无"));
}
}
// 支付处理处理器
class PaymentHandler implements OrderHandler {
@Override
public boolean preHandle(Order order) {
System.out.println("支付处理成功,支付金额:" + order.getAmount());
return true;
}
@Override
public void postHandle(Order order) {
System.out.println("支付处理处理器:postHandle 操作完成。");
}
@Override
public void afterCompletion(Order order, Exception ex) {
System.out.println("支付处理处理器:afterCompletion 操作完成,异常信息:" + (ex != null ? ex.getMessage() : "无"));
}
}
// 订单完成处理器
class OrderCompletionHandler implements OrderHandler {
@Override
public boolean preHandle(Order order) {
System.out.println("订单 " + order.getOrderId() + " 处理完成。");
return true;
}
@Override
public void postHandle(Order order) {
System.out.println("订单完成处理器:postHandle 操作完成。");
}
@Override
public void afterCompletion(Order order, Exception ex) {
System.out.println("订单完成处理器:afterCompletion 操作完成,异常信息:" + (ex != null ? ex.getMessage() : "无"));
}
}
// 责任链构建器(改为维护处理器列表)
class OrderHandlerChainBuilder {
private List<OrderHandler> handlers = new ArrayList<>();
public OrderHandlerChainBuilder addHandler(OrderHandler handler) {
handlers.add(handler);
return this;
}
public List<OrderHandler> build() {
return handlers;
}
}
// 测试类
public class OrderChainTest {
public static void main(String[] args) {
// 创建处理器
OrderValidatorHandler validator = new OrderValidatorHandler();
InventoryCheckHandler inventoryCheck = new InventoryCheckHandler();
PaymentHandler payment = new PaymentHandler();
OrderCompletionHandler completion = new OrderCompletionHandler();
// 构建责任链
OrderHandlerChainBuilder builder = new OrderHandlerChainBuilder();
List<OrderHandler> handlers = builder.addHandler(validator)
.addHandler(inventoryCheck)
.addHandler(payment)
.addHandler(completion)
.build();
// 创建订单
Order validOrder = new Order("123", 100.0, 5);
Order invalidOrder = new Order("456", -10.0, 20);
// 处理有效订单
System.out.println("处理有效订单:");
processOrder(validOrder, handlers);
// 处理无效订单
System.out.println("\n处理无效订单:");
processOrder(invalidOrder, handlers);
}
private static void processOrder(Order order, List<OrderHandler> handlers) {
List<OrderHandler> executedHandlers = new ArrayList<>();
boolean processSuccess = true;
Exception exception = null;
// 按顺序执行preHandle
for (OrderHandler handler : handlers) {
boolean result = handler.preHandle(order);
executedHandlers.add(handler);
if (!result) {
processSuccess = false;
break;
}
}
try {
if (processSuccess) {
// 如果全部preHandle成功,逆序执行postHandle
for (int i = executedHandlers.size() - 1; i >= 0; i--) {
executedHandlers.get(i).postHandle(order);
}
// 如果全部preHandle成功,逆序执行afterCompletion
for (int i = executedHandlers.size() - 1; i >= 0; i--) {
executedHandlers.get(i).afterCompletion(order, exception);
}
}
} catch (Exception e) {
exception = e;
}
System.out.println("订单处理结果:" + (processSuccess ? "成功" : "失败"));
}
}
执行结果
总结
- 责任链设计模式可以抽象成一个链表来理解,单链表和双链表
- spring 中的interceptors 是 用List抽象的双链表