目录
1 Compileflow
1.1 简介
compileflow
是一个非常轻量、高性能、可集成、可扩展的流程引擎。
compileflow Process
引擎是淘宝工作流 TBBPM
引擎之一,是专注于纯内存执行,无状态的流程引擎,通过将流程文件转换生成 java
代码编译执行,简洁高效。当前是阿里业务中台交易等多个核心系统的流程引擎。
compileflow
能让开发人员通过流程编辑器设计自己的业务流程,将复杂的业务逻辑可视化,为业务设计人员与开发工程师架起了一座桥梁。
1.2 特点
功能列表:
- 高性能:通过将流程文件转换生成 java 代码编译执行,简洁高效。
- 丰富的应用场景:在阿里巴巴中台解决方案中广泛使用,支撑了导购、交易、履约、资金等多个业务场景。
- 可集成:轻量、简洁的设计使得可以极其方便地集成到各个解决方案和业务场景中。
- 完善的插件支持:流程设计目前有 IntelliJ IDEA、Eclipse 插件支持,可以在流程设计中实时动态生成 java 代码并预览,所见即所得。
- 支持流程设计图导出 svg 文件和单元测试代码。
- 支持基于 Java 反射和 Spring 容器的代码触发
1.3 Compileflow插件下载
由于Idea插件市场没有,需要自己手动下载导入,根据各个版本自动下载
https://gitcode.com/mirrors/compileflow/compileflow-designer-upgrade/overview
使用本地安装的方式安装,注意安装整个zip
不用手动解压
重启IntelliJ IDEA就会生效
1.4 main方法调用
1.4.1 pom.xml
compileflow jar 依赖
<dependency>
<groupId>com.alibaba.compileflow</groupId>
<artifactId>compileflow</artifactId>
<version>1.0.0</version>
</dependency>
1.4.2 新建bpm文件
示例,新建一个account.bpm文件,选择ProcessFlow
,进行可视化编辑
先创建开始和结束后,添加判断节点:
如图,此处是验证用户名节点,以此类推创建验证密码和验证验证码节点
其中的连接节点是条件是result==true的通过,不然不通过
最后,双击编辑页空白处,配置全局参数
1.4.3 各个节点绑定方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
private String password;
private String name;
private String verificationCode;
}
public class AccountVerify {
public boolean verifyName(Account account) {
if (StringUtils.isNotEmpty(account.getName())) {
System.out.println("name认证通过");
return true;
}
System.out.println("name认证不通过");
return false;
}
public boolean verifyPassword(Account account) {
if (StringUtils.isNotEmpty(account.getPassword())) {
System.out.println("密码认证通过");
return true;
}
System.out.println("密码认证不通过");
return false;
}
public boolean verifyVerificationCode(Account account) {
if (StringUtils.isNotEmpty(account.getVerificationCode())) {
System.out.println("验证码认证通过");
return true;
}
System.out.println("验证码认证不通过");
return false;
}
}
1.4.4 测试方法
import cn.flow.entity.Account;
import com.alibaba.compileflow.engine.ProcessEngine;
import com.alibaba.compileflow.engine.ProcessEngineFactory;
import java.util.HashMap;
import java.util.Map;
public class CompileFlowTest {
public static void main(String[] args) {
Account account = new Account();
account.setName("haha");
account.setPassword("pwd");
account.setVerificationCode("1111");
//找到bpm文件的位置 如果是在包中,bpm/account.bpm 则为 bpm.account
String code = "account";
//设置上下文
Map<String, Object> context = new HashMap<>();
context.put("account", account);
try {
//执行流程
ProcessEngine processEngine = ProcessEngineFactory.getProcessEngine();
Map<String, Object> result = processEngine.execute(code, context);
// 处理其他业务逻辑
if (Boolean.parseBoolean(result.get("result").toString())) {
System.out.println("认证通过");
} else {
System.out.println("认证不通过");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.5 bpm各个标签说明
1.5.1 BPM根节点
<bpm code="bpm.testStudy" name="testStudy" type="process" description="This is test demo."></bpm>
code
:该属性最重要,当引擎start
执行流程时,会要求传入code
参数,这个参数就是流程文件中的code
字段,code
约定用点
表示文件存放目录层级
type
:目前固定写死process
,后续可扩展支持多种类型流程.name
:按自己工程需要命名description
:按自己工程需要命名.
1.5.2 全局变量
<var name="account" description="入参" dataType="cn.flow.entity.Account" inOutType="param"/>
<var name="result" description="出参" dataType="java.lang.Boolean" inOutType="return"/>
参数用var
节点表示,直接在根节点bpm
下的就叫全局参
inOutType属性
:表示参数类型,值有3种:param、inner、return
param
:表示对应引擎start
的入参,当我们start
流程时,除了需要设置code
,还需要设置contex
,它是一个MAP
,其中key
就需要映射成上面var
节点的name
属性inner
:表示内部运行时各个节点执行后的中间变量.return
:表示返回结果变量,流程执行完成后,我们拿到了一个result
结果,是个MAP,其中指定了return类型的var节点,我们可以通过name
作为key从result拿到值.
dataType
:参数类型,支持java类型写法例如上面的: java.lang.Booleanname
:变量名称description
:变量描述
1.5.3 开始节点: start
<start id="1" name="开始" tag="223" g="105,17,30,30">
流程的开始节点用start
表示.
transition
:表示指向下一个节点.to
:就是下一个节点的id.id
:节点的唯一标志,请保持唯一tag
:节点的附加数据name
:节点名称会在流程图上显示g
:布局
1.5.4 结束节点: end
<end id="11" name="结束" tag="已经结束" g="101,549,30,30">
id
:节点的唯一标志,请保持唯一tag
:节点的附加数据name
:节点名称会在流程图上显示g
:布局
1.5.5 自动节点: autoTask--流程节点
<autoTask id="1705217851098" name="自动节点" tag="123" g="405,190,90,50">
<action type="java">
<actionHandle clazz="cn.flow.verify.AccountVerify" method="verifyVerificationCode">
<var name="account" dataType="cn.flow.entity.Account" contextVarName="account" inOutType="param"/>
<var name="boolean" dataType="java.lang.Boolean" contextVarName="result" inOutType="return"/>
</actionHandle>
</action>
</autoTask>
自动节点用autoTask
表示是最常见的,主要执行一段逻辑.目前支持springBean
的配置和普通javaBean
的配置.其中action
就是要配置的动作.下面actionHandle
配置该动作出入参.最终这个节点会被编译成javaCode如下:
1.5.6 判断节点: decision
<decision id="1705213493244" name="验证验证码" g="250,310,90,50">
<transition to="11" name="通过验证码验证" expression="result==true"/>
<transition to="11" name="没通过验证码验证" expression="result==false"/>
<action type="java">
<actionHandle clazz="cn.flow.verify.AccountVerify" method="verifyVerificationCode">
<var name="account" dataType="cn.flow.entity.Account" contextVarName="account" inOutType="param"/>
<var name="boolean" dataType="java.lang.Boolean" contextVarName="result" inOutType="return"/>
</actionHandle>
</action>
</decision>
判断节点用decision
表示,主要执行一段逻辑,然后根据执行后的逻辑值进行表达式判断后,再走不同的分支
1.5.7 脚本节点: scriptTask
<scriptTask id="9" name="成功" g="132,189,88,48">
<var name="locationId" description="地址id" dataType="java.lang.Integer" contextVarName="locationId" inOutType="param">
脚本节点和自动节点差不多含义,就是执行一段逻辑,只是自动节点可以执行一个springBean或者一个javaBean
,而脚本节点指定的是一个表达式,目前支持QL
表示环境执行,ql 表达式是一种类似于 SQL 的查询语言,用于对数据进行过滤、排序、聚合等操作。它可以在脚本节点中使用,以便在工作流程执行期间对数据进行处理。
1.5.8 循环节点
<loopProcess id="13" name="循环节点" collectionVarName="pList" variableName="p" indexVarName="i" variableClass="java.lang.String" startNodeId="13-1" endNodeId="13-1" g="20,75,198,190">
<transition to="8" g=":-15,20"></transition>
<autoTask id="13-1" name="每人唱一首歌" g="50,80,88,48">
<action type="spring-bean">
<actionHandle bean="mockSpringBean" clazz="com.alibaba.compileflow.demo.mock.MockSpringBean" method="sing">
<var name="p1" dataType="java.lang.String" contextVarName="p" inOutType="param"></var> </actionHandle> </action>
</autoTask>
</loopProcess>
循环节点的作用是,包裹部分流程进行循环执行,collectionVarName
表示要循环的列表变量,variableName
表示每个循环的局部变量,indexVarName
表示循环的次数