使用Spring(SpringBoot)进行自动装配链表(处理器链模式)

项目中用到了一个订单需要经过多层处理的业务,于是想到了使用链式处理,处理器链中某个节点抛出错误就会中止,如果有事务也是可以回滚的。

核心是使用@Order注解和@Configuration自动配置(可以另外使用单独外观类进行状态)

步骤

定义抽象处理器链

**
 * @author SYM
 * @date 2022/12/24 20:45
 * @Description 抽象处理器链
 */
public abstract class AbstractChain {

    /**
     * 下一节点
     */
    private AbstractChain next;

    /**
     * 执行链
     *
     * @param args 参数
     */
    public void doChain(Object... args) {
        this.handle(args);
        // 交由下一节点处理
        if (this.next != null) {
            this.next.doChain(args);
        }
    }

    /**
     * 处理方法
     *
     * @param args 参数
     */
    public abstract void handle(Object... args);

    public void setNext(AbstractChain next) {
        this.next = next;
    }
}

定义类排序常量

用于方便地改动链节点顺序

/**
 * @author SYM
 * @date 2022/12/24 20:52
 * @Description 链表顺序
 */
public class ChainOrder {
    public static final int CHAIN_1 = 1;
    public static final int CHAIN_2 = 2;
    public static final int CHAIN_3 = 3;
}

实现节点

每个节点分别处理一些业务,实现业务解耦

@Order注解会在@Autowired等注解自动注入时,如果使用List数组等注入时自动排序。

/**
 * @author SYM
 * @date 2022/12/24 20:51
 * @Description 处理器链1
 */
@Component
@Order(ChainOrder.CHAIN_1)
public class Chain1 extends AbstractChain {
    @Override
    public void handle(Object... args) {
        System.out.println("订单入库");
    }
}
/**
 * @author SYM
 * @date 2022/12/24 20:51
 * @Description 处理器链1
 */
@Component
@Order(ChainOrder.CHAIN_2)
public class Chain2 extends AbstractChain {
    @Override
    public void handle(Object... args) {
        System.out.println("优惠计算");
    }
}
/**
 * @author SYM
 * @date 2022/12/24 20:51
 * @Description 处理器链1
 */
@Component
@Order(ChainOrder.CHAIN_3)
public class Chain3 extends AbstractChain {
    @Override
    public void handle(Object... args) {
        System.out.println("发起支付");
    }
}

装配链表

本质上都是使用自动注入+遍历装配

配置装配

/**
 * @author SYM
 * @date 2022/12/24 20:55
 * @Description
 */
@Configuration
public class ChainConfig {

    /**
     * 向外返回一个名称的Bean
     *
     * @param chainList
     * @return
     */
    @Autowired
    @Bean("handleChain")
    public AbstractChain handleChain(List<AbstractChain> chainList) {
        // 组装链表
        Iterator<AbstractChain> iterator = chainList.iterator();
        AbstractChain temp = iterator.next();
        while (iterator.hasNext()) {
            AbstractChain next = iterator.next();
            temp.setNext(next);
            temp = next;
        }
        // 返回链表首个节点
        return chainList.get(0);
    }

}

类装配

/**
 * @author SYM
 * @date 2022/12/24 21:11
 * @Description 处理器链组装,向外固定暴露一个处理器
 */
@Component
public class HandlerChainFacade {

    /**
     * 链表首个处理节点
     */
    private AbstractChain chain;

    /**
     * 自动创配链表
     *
     * @param chains
     */
    @Autowired
    private void autoLoad(AbstractChain... chains) {
        List<AbstractChain> chainList = Arrays.asList(chains);
        // 组装链表
        Iterator<AbstractChain> iterator = chainList.iterator();
        AbstractChain temp = iterator.next();
        while (iterator.hasNext()) {
            AbstractChain next = iterator.next();
            temp.setNext(next);
            temp = next;
        }
        this.chain = chainList.get(0);
    }

    /**
     * 处理方法
     *
     * @param args 参数
     */
    public void doChain(Object... args) {
        this.chain.doChain(args);
    }

}

结语

作者认为,开发过程中,有意无意地使用设计模式是一种非常好的编码习惯。合理使用设计模式可以使代码更加简洁、业务逻辑更加分明,整体逻辑更加清晰。

如果各位有其他更好的想法或者问题,欢迎在留下您宝贵的评论,愿能在代码路上共同进步!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值