java流程引擎实现_手写实现一套流程编排

本文介绍了流程编排在应对日益复杂的业务流程时的重要性。通过流程配置化、能力复用和业务细节聚合,可以清晰地组织业务规则,降低开发和维护成本。文章还展示了如何设计一个简单的流程编排系统,包括上下文、事务执行模板和流程引擎的具体实现,并提供了一个测试用例来演示其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自:https://blog.csdn.net/weixin_39631301/article/details/112082970

流程编排

随着业务的不断发展,业务流程迭代慢慢变得复杂了起来,全景不清晰,这不仅仅会使开发人员编写代码弄的’ 不敢改 '心理,以及出现问题不好寻找出错位置,历史包袱太重,影响面需要评估,等等。
一个本来很简单的需求,但是由于很多历史背景和包袱导致侵入代码需要评估改动影响面很大,这时候就需要一套流程编排来使得流程清晰,能全局感受到业务的能力地图。减少开发、测试等的维护迭代成本。

流程编排特点

流程配置化

通过配置化的方式形成业务规则,通过插拔某些组件形成新的规则,每条规则对应一个业务身份(比如,“餐饮商品下单”就是一个业务身份),当我们需要新增业务身份,其实就是在对能力进行聚合编排,最终配置成我们需要的业务规则。

能力复用

在更多的业务身份产生的同时,更多的业务能力也被我们沉淀下来,能力会被编排进更多的业务规则中,在各个规则中复用。

业务细节聚合

在传统模式中,随着需求的不断迭代以及开发人员不同的编码习惯,越来越多的业务逻辑被分散在各个代码模块,给后续业务的理解和迭代造成很大的困难,而通过流程编排,不同的能力被分组聚合,各个能力职责单一,校验只做校验,装配只做装配。

通过执行引擎,实现技术细节和业务逻辑的分离

开发人员只需要定规则,具体的执行完全由执行引擎调度,强大的执行引擎通过其本身复杂的实现而让开发者获得更好的编码体验,如跨组件事务,依赖注入,监控等。

流程编排组件

参数校验 – 业务校验 – 事务前置扩展点 – 业务参数装配 – 事务执行 – 事务结果装配 – 事务后置扩展点
备注:节点不固定,根本具体业务评估需要哪些组件。

流程编排实现

下面我们就简单实现一个demo级的流程编排例子。
能力流程编排的各个组件我们通过上下文使它们环环相扣,定义如下:

package com.orangecsong.st.template;
 
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * @Description: 上下文
 * @author: orangeCs
 * @create: 2020-08-22
 */
public class Context implements Serializable {
 
    private final Map<Class<?>,Object> CONTEXT = new ConcurrentHashMap<>();
 
    public <T> T get(Class<T> clazz) {
        return (T) CONTEXT.get(clazz);
    }
 
    public void put(Object obj) {
        if(null == obj) {
            return;
        }
        CONTEXT.put(obj.getClass(),obj);
    }
}

事务执行模板,定义组件之间api,为了通用,我们这里将上下文注射到回调模板的泛型参数中

package com.orangecsong.st.template;
 
import com.orangecsong.bizclass.BaseResult;
 
/**
 * @Description: 流程引擎-执行事件接口
 * @author: orangeCs
 * @create: 2020-08-22
 */
public interface ActionCallBack<T extends BaseResult, C extends Context> {
 
    void paramValidate(C context);
 
    void bizValidate(C context);
 
    void beforeProcess(C context);
 
    void process(C context);
 
    void afterProcess(C context);
 
    T assemble(C context);
}

考虑到某些业务无需扩展点交互,为此我们抽象出来。

package com.orangecsong.st.template;
 
import com.orangecsong.bizclass.BaseResult;
 
/**
 * @Description: 流程引擎-抽象执行事件接口
 * @author: orangeCs
 * @create: 2020-08-22
 */
public abstract class AbstractActionCallBack<T extends BaseResult,C extends Context> implements ActionCallBack<T,C>{
 
    @Override
    public void beforeProcess(C context) {
 
    }
 
    @Override
    public void afterProcess(C context) {
 
    }
}

接下来我们定义流程引擎具体实现类

package com.orangecsong.st.template;
 
import com.orangecsong.bizclass.BaseResult;
 
/**
 * @Description: 通用的执行器
 * @author: orangeCs
 * @create: 2020-08-22
 */
public class GeneralActionCallBack extends AbstractActionCallBack<BaseResult,Context> {
 
    @Override
    public void paramValidate(Context context) {
 
    }
 
    @Override
    public void bizValidate(Context context) {
 
    }
 
    @Override
    public void process(Context context) {
 
    }
 
    @Override
    public BaseResult assemble(Context context) {
        return null;
    }
}

为了业务流程中调用,我们封装对外调用API ,传入对应上下文、回调函数即可。

package com.orangecsong.st.template;
 
import com.orangecsong.bizclass.BaseResult;
 
/**
 * @Description:
 * @author: orangeCs
 * @create: 2020-08-22
 */
public interface ServiceTemplate<T extends BaseResult,C extends Context> {
 
    /**
     * @param context
     * @param action
     * @return
     */
    T invoke(C context, AbstractActionCallBack<T, C> action);
}

对业务无感知的流程引擎实现

package com.orangecsong.st.template;
 
import com.orangecsong.bizclass.BaseResult;
 
/**
 * @Description: 服务模板
 * @author: orangeCs
 * @create: 2020-08-22
 */
public class ServiceTemplateImpl implements ServiceTemplate{
 
    @Override
    public BaseResult invoke(Context context, AbstractActionCallBack action) {
 
            //参数校验
            paramValidate(context, action);
            //业务校验
            bizValidate(context, action);
            //事务执行前置扩展点
            beforeProcessCallBack(context, action);
            //事务执行
            processCallBack(context, action);
            //事务执行后置扩展点
            afterProcessCallBack(context, action);
            //数据装配
            return assemble(context, action);
        }
 
    private BaseResult assemble (Context context, AbstractActionCallBack action){
        System.out.println("assemble");
        return action.assemble(context);
    }
 
    private void afterProcessCallBack (Context context, AbstractActionCallBack action){
        System.out.println("afterProcessCallBack");
        action.afterProcess(context);
    }
 
    private void processCallBack (Context context, AbstractActionCallBack action){
        System.out.println("processCallBack");
        action.process(context);
    }
 
    private void beforeProcessCallBack (Context context, AbstractActionCallBack action){
        System.out.println("beforeProcessCallBack");
        action.beforeProcess(context);
    }
 
    private void bizValidate (Context context, AbstractActionCallBack action){
        System.out.println("bizValidate");
        action.bizValidate(context);
    }
 
    private void paramValidate (Context context, AbstractActionCallBack action){
        System.out.println("paramValidate");
        action.paramValidate(context);
    }
}

最后我们写个测试程序测试一下

package com.orangecsong.st.client;
 
import com.orangecsong.bizclass.BaseResult;
import com.orangecsong.st.template.Context;
import com.orangecsong.st.template.ServiceTemplate;
import com.orangecsong.st.template.ServiceTemplateImpl;
 
/**
 * @Description: 测试服务模板流程引擎调用
 * @author: orangeCs
 * @create: 2020-08-22
 * <pre>
 *     查询学生为某某某的人
 *     paramValidate 学生id不能为空 且大于0
 *     bizValidate 学生姓名不能带“cute”
 *     process 查询db 得到结果
 * </pre>
 */
public class ServiceTemplateInvoke {
    public static void main(String[] args) {
        //构造上下文
        Context context = new Context();
        context.put(10);
 
        StudentAction studentAction = new StudentAction();
 
        ServiceTemplate serviceTemplate = new ServiceTemplateImpl();
        final BaseResult invoke = serviceTemplate.invoke(context, studentAction);
        System.out.println(invoke.getData());
    }
}

最后强调一下,任务技术的引入都是一把双刃剑,我们还是需要根据具体的场景和业务评估采取哪种方式,如果业务简单,流程不复杂,我们引入了流程引擎,一是增加了对流程引擎使用了解的成本,二是杀鸡用牛刀,工具的使用宗旨是让我们处理高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值