引言
责任链模式定义了一种松散耦合的方式来处理请求。它创建了一个接收者对象的链,每个接收者都包含对下一个接收者的引用。这样,客户端只需要向链中的第一个接收者发送请求,然后由链上的接收者依次判断是否处理该请求或者继续传递给下一个接收者。
图片
本文将探讨如何在Spring Boot项目中巧妙地应用责任链模式来构建更加灵活、易于扩展的应用架构,并通过一个完整的订单处理流程案例展示其强大之处。
代码实践
首先,我们需要定义一个通用的处理器接口,所有具体的处理器都将实现这个接口。
public interface OrderHandler {
void setNext(OrderHandler next);
void handle(OrderEntity order);
}
接下来,根据业务需求创建不同的处理器类,比如支付验证、库存检查、发货准备等。
@Order(1)
@Component
public class PaymentVerificationHandler implements OrderHandler {
private OrderHandler next;
@Override
public void setNext(OrderHandler next) {
this.next = next;
}
@Override
public void handle(OrderEntity order) {
// 模拟支付验证逻辑
if (order.isPaymentValid()) {
System.out.println("支付验证通过");
if (next != null) {
next.handle(order);
}
} else {
System.out.println("支付失败");
}
}
}
@Order(2)
@Component
public class InventoryCheckHandler implements OrderHandler {
private OrderHandler next;
@Override
public void setNext(OrderHandler next) {
this.next = next;
}
@Override
public void handle(OrderEntity order) {
// 模拟库存检查逻辑
if (order.isInventoryAvailable()) {
System.out.println("库存充足");
if (next != null) {
next.handle(order);
}
} else {
System.out.println("库存不足");
}
}
}
@Order(3)
@Component
public class ShippingPreparationHandler implements OrderHandler {
private OrderHandler next;
@Override
public void setNext(OrderHandler next) {
this.next = next;
}
@Override
public void handle(OrderEntity order) {
// 模拟发货准备逻辑
System.out.println("开始准备发货");
// 这里可以添加更多的发货准备逻辑
}
}
使用Spring的依赖注入功能自动装配处理器链。
@Configuration
public class OrderChainConfig {
//Spring的ioc容器,支持通过Map或者List来直接注入对象,可以省去自己排序。
@Autowired
private List<OrderHandler> handlers;
@Bean
public OrderHandler orderHandler() {
OrderHandler last = null;
for (int i = handlers.size() - 1; i >= 0; i--) {
OrderHandler handler = handlers.get(i);
if (last != null) {
handler.setNext(last);
}
last = handler;
}
return last;
}
}
测试与运行。
@Autowired
private OrderHandler orderHandler;
@Test
@DisplayName("责任链")
public void orderChain(){
OrderEntity orderEntity = new OrderEntity();
orderEntity.setPaymentValid(true);
orderEntity.setInventoryAvailable(true);
orderHandler.handle(orderEntity);
}