Java责任链模式Demo

责任链模式是一种行为设计模式,它允许构建一个由多个对象组成的链,每个对象都有机会处理请求,或者将请求传递给链中的下一个对象。这种模式的使用场景主要包括但不限于:日志处理、权限验证、资源分配、异常处理等

我个人使用的场景为:下单接口的验证,当一个商品下单时,要对当前订单进行一系列的校验,并且不同的校验涉及到不同的服务和逻辑,当其中任意一个校验不通过时,都会返回失败,所以将每一个校验当做每一个链,每一个链执行完后指向下一个链。

1.定义处理接口

public interface ContextHandler {
    void setNext(ContextHandler handler);
    void setPre(ContextHandler handler);
    void handle(GlobalContext param);
    void rollback(GlobalContext param);
}

2.定义全局上下文参数

@Data
public class GlobalContext {
    private String orderId;
    private String payFee;
}

3.定义处理器抽象类

public abstract class AbstractContextHandler implements ContextHandler {
 
    protected ContextHandler pre;
    protected ContextHandler next;
 
    @Override
    public void handle(GlobalContext param) {
        try {
            this.doHandler(param);
            if (next != null) {
                next.handle(param);
            }
        } catch (Exception e) {
            if (pre != null) {
                pre.rollback(param);
            }
        }
    }
 
    @Override
    public void rollback(GlobalContext param) {
        this.doRollback(param);
    }
 
    abstract void doHandler(GlobalContext param);
    abstract void doRollback(GlobalContext param);
 
    @Override
    public void setNext(ContextHandler handler) {
        this.next = handler;
    }
 
    @Override
    public void setPre(ContextHandler handler) {
        this.pre = handler;
    }
 
}

4.定义每个执行单元业务处理handler,(order从小到大执行)

@Component
@Order(2)
public class BuniessPayHandler extends AbstractContextHandler {
 
    @Override
    void doHandler(GlobalContext param) {
        System.out.println("BuniessPayHandler业务处理doHandler");
    }
 
    @Override
    void doRollback(GlobalContext param) {
 
    }
}
 
@Component
@Order(1)
public class BuniessProductHandler extends AbstractContextHandler {
 
    @Override
    void doHandler(GlobalContext param) {
        System.out.println("BuniessProductHandler业务处理doHandler");
    }
 
    @Override
    void doRollback(GlobalContext param) {
 
    }
}

5.定义责任链配置(项目启动时初始化执行顺序,以及调用执行入口)

@Component
public class Chain {
 
    @Resource
    private List<ContextHandler> handlerList;
    private ContextHandler header;
 
    @PostConstruct
    public void init() {
        if (CollectionUtils.isEmpty(handlerList)) {
            return;
        }
        ContextHandler pre = null;
        ListIterator<ContextHandler> iterator = handlerList.listIterator();
        while (iterator.hasNext()) {
            ContextHandler handler = iterator.next();
            if (header == null) {
                header = handler;
            }
            handler.setPre(pre);
            pre = handler;
            if (iterator.hasNext()) {
                handler.setNext(iterator.next());
                iterator.previous();
            }
        }
    }
 
    public void handler(GlobalContext param) {
        if (header == null) {
            return;
        }
        header.handle(param);
    }
}

6.单元测试

 @Autowired
    private Chain chain;
 
    @GetMapping("/test")
    public WebResponse<BrandRelationResult> test(GlobalContext param) {
        chain.handler(param);
        return null;
    }