Spring小技巧之设计模式
责任链模式
模式定义
- 该模式在《图解设计模式》的第14章节《Chain of Responsibility模式》有详细的介绍。简单来说:当一个对象需要交给多个处理类依次处理的时候就可以用责任链模式,Servlet Filter、Spring 拦截器链都是这一模式的实际应用,在订单履约等业务场景中也经常使用到。
示例代码
-
OrderCreatedBaseHandler:责任链顶层接口定义类,所有处理器都实现该接口。
javapackage com.wwq.test; /** * 创建订单责任链接口 */ public interface OrderCreatedBaseHandler { /** * 运行消息处理 */ void run(Order order); /** * 是否执行</br> * 子类重写该方法,可根据配置开关,来确定是否执行 run 方法 */ default boolean isRun(Order order){ return true; } } -
OrderCreatedOperate:责任链执行器类,是整个责任链的管理容器和启动入口。利用Spring批量注入接口实现类为List的机制串联整个链条。
javapackage com.wwq.test; /** * 责任链执行器,运行所有 OrderCreatedBaseHandler 实现类 */ @Component public class OrderCreatedOperate { /* * 注入全部处理器 */ @Autowired private List<OrderCreatedBaseHandler> baseOrderCreatedHandles; /** * 运行消息处理 * @param orderCreatedMessage 订单创建消息 */ public void run(Order order) { for(OrderCreatedBaseHandler handler : baseOrderCreatedHandles){ if(handler.isRun(order)){ handler.run(order); } } } } -
各个责任链处理,可通过@Order注解调整他们的执行顺序。
javapackage com.wwq.test; /** * 创建订单处理器 */ @Slf4j @Component public class OrderCreatedHandler implements OrderCreatedBaseHandler { public void run(OrderCreatedMessage orderCreatedMessage){ // TODO 创建订单 } }javapackage com.wwq.test; /** * 积分处理器 */ @Slf4j @Component public class PointHandler implements OrderCreatedBaseHandler { public void run(OrderCreatedMessage orderCreatedMessage){ // TODO 积分抵扣和发送 } }javapackage com.wwq.test; /** * 物流处理器 */ @Slf4j @Component public class LogisticsHandler implements OrderCreatedBaseHandler { public void run(OrderCreatedMessage orderCreatedMessage){ // TODO 处理物流流程信息 } }javapackage com.wwq.test; /** * 商品库存处理器 */ @Slf4j @Component public class StockHandler implements OrderCreatedBaseHandler { public void run(OrderCreatedMessage orderCreatedMessage){ // TODO 库存扣减 } } -
如果想各个处理器并行执行,可以使用 CompletableFuture.runAsync() 提交异步任务。
javapackage com.wwq.test; /** * 责任链执行器,运行所有 OrderCreatedBaseHandler 实现类 */ @Component public class OrderCreatedOperate { /* * 责任链执行线程池 */ @Autowired @Qualifier("orderCreatedTaskExecutor") private Executor orderCreatedTaskExecutor; /* * 注入全部处理器 */ @Autowired private List<OrderCreatedBaseHandler> baseOrderCreatedHandles; /** * 运行消息处理 * @param orderCreatedMessage 订单创建消息 */ public void run(Order order) { /* * 收集 Future */ List<CompletableFuture<?>> futures = new ArrayList<>(); /* * 异步执行每个处理器 */ for(OrderCreatedBaseHandler handler : baseOrderCreatedHandles){ futures.add(CompletableFuture.runAsync(() -> { if(handler.isRun(order)){ handler.run(order); } }, orderCreatedTaskExecutor)); } /* * 等待所有异步任务全部执行完毕 */ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); } }
策略模式模式
模式定义
- 该模式在《图解设计模式》的第10章节《Strategy模式》有详细的介绍。当需要根据某种条件整体替换运算逻辑时就可以使用策略模式,在支付渠道、文件解析、报表导出、优惠计算等场景都有应用。
示例代码
-
策略接口定义
javapublic interface PayStrategy { // 渠道标识 String getChannel(); // 支付逻辑 void pay(BigDecimal amount); } -
策略实现
java@Component public class AliPayStrategy implements PayStrategy { @Override public String getChannel() { return "ALI"; } @Override public void pay(BigDecimal amount) { System.out.println("支付宝支付:" + amount); } }java@Component public class WxPayStrategy implements PayStrategy { @Override public String getChannel() { return "WX"; } @Override public void pay(BigDecimal amount) { System.out.println("微信支付:" + amount); } } -
策略工厂
java@Service public class PayStrategyFactory { // 自动注入全部策略实现 private final Map<String, PayStrategy> strategyMap; @Autowired public PayStrategyFactory(List<PayStrategy> payStrategies) { this.strategyMap = new HashMap<>(); for(PayStrategy strategy : payStrategies){ strategyMap.put(strategy.getChannel(), strategy); } } // 根据渠道获取对应策略 public PayStrategy getStrategy(Integer channel) { return strategyMap.get(channel); } } -
使用策略
java@Autowired private PayStrategyFactory factory; public void test() { PayStrategy ali = factory.getStrategy("ALI"); ali.pay(new BigDecimal("100")); }