https://gitee.com/mirrors/compileflow
compileflow是一个非常轻量、高性能、可集成、可扩展的流程引擎。
compileflow Process引擎是淘宝工作流TBBPM引擎之一,是专注于纯内存执行,无状态的流程引擎,通过将流程文件转换生成java代码编译执行,简洁高效。当前是阿里业务中台交易等多个核心系统的流程引擎。
compileflow能让开发人员通过流程编辑器设计自己的业务流程,将复杂的业务逻辑可视化,为业务设计人员与开发工程师架起了一座桥梁。
<?xml version="1.0" encoding="UTF-8" ?>
<bpm code="bpm.ktv.ktvExample" name="ktv example" type="process" description="ktv example">
<var name="price" description="支付价格" dataType="java.lang.Integer" inOutType="return"/>
<var name="totalPrice" description="实付价" dataType="java.lang.Integer" inOutType="inner"/>
<var name="pList" description="人员" dataType="java.util.List<java.lang.String>" inOutType="param"/>
<end id="11" name="结束" g="101,549,30,30"/>
<autoTask id="12" name="付款" g="72,469,88,48">
<transition g=":-15,20" to="11"/>
<action type="java">
<actionHandle clazz="com.charles.test.KtvService" method="payMoney">
<var name="p1" description="价格" dataType="java.lang.Integer" contextVarName="price" defaultValue=""
inOutType="param"/>
</actionHandle>
</action>
</autoTask>
<scriptTask id="9" name="原价" g="132,389,88,48">
<transition g=":-15,20" to="12"/>
<action type="ql">
<actionHandle expression="price*1">
<var name="price" description="价格" dataType="java.lang.Integer" contextVarName="totalPrice"
defaultValue="" inOutType="param"/>
<var name="price" description="价格" dataType="java.lang.Integer" contextVarName="price" defaultValue=""
inOutType="return"/>
</actionHandle>
</action>
</scriptTask>
<loopProcess id="13" name="循环节点" g="20,75,198,190" collectionVarName="pList" variableName="p" indexVarName="i"
variableClass="java.lang.String" startNodeId="13-1" endNodeId="13-1">
<transition g=":-15,20" to="8"/>
<autoTask id="13-1" name="每人唱一首歌" g="70,95,88,48">
<action type="spring-bean">
<actionHandle bean="ktvService" clazz="com.charles.test.KtvService" method="sing">
<var name="p1" description="" dataType="java.lang.String" contextVarName="p" defaultValue=""
inOutType="param"/>
</actionHandle>
</action>
</autoTask>
</loopProcess>
<decision id="8" name="计算费用" g="72,309,88,48">
<transition expression="" name="不超过400" priority="1" g=":-15,20" to="9"/>
<transition expression="totalPrice>=400" name="超过400" priority="10" g=":-15,20" to="10"/>
<action type="java">
<actionHandle clazz="com.charles.test.MockJavaClazz" method="calPrice">
<var name="p1" description="人数" dataType="java.lang.Integer" contextVarName="pList.size()"
defaultValue="" inOutType="param"/>
<var name="p2" description="价格" dataType="java.lang.Integer" contextVarName="totalPrice" defaultValue=""
inOutType="return"/>
</actionHandle>
</action>
</decision>
<start id="1" name="开始" g="105,17,30,30">
<transition g=":-15,20" to="13"/>
</start>
<note id="14" g="273,82,93,55" comment="外框为循环节点" visible="true">
<transition g=":-15,20" to="13"/>
</note>
<scriptTask id="10" name="9折优惠" g="12,389,88,48">
<transition g=":-15,20" to="12"/>
<action type="ql">
<actionHandle expression="(round(price*0.9,0)).intValue()">
<var name="price" description="价格" dataType="java.lang.Integer" contextVarName="totalPrice"
defaultValue="" inOutType="param"/>
<var name="price" description="价格" dataType="java.lang.Integer" contextVarName="price" defaultValue=""
inOutType="return"/>
</actionHandle>
</action>
</scriptTask>
</bpm>
@Test
public void testProcessEngine() {
final String code = "bpm.ktvExample";
final Map<String, Object> context = new HashMap<>();
final List<String> pList = new ArrayList<>();
pList.add("wuxiang");
pList.add("xuan");
pList.add("yusu");
context.put("pList", pList);
final ProcessEngine<TbbpmModel> processEngine = ProcessEngineFactory.getProcessEngine();
final TbbpmModel tbbpmModel = processEngine.load(code);
final OutputStream outputStream = TbbpmModelConverter.getInstance().convertToStream(tbbpmModel);
System.out.println(outputStream);
System.out.println(processEngine.getTestCode(code));
processEngine.preCompile(code);
System.out.println(processEngine.execute(code, context));
}
AbstractProcessEngine#load
是将xml文件编译成java对象。AbstractProcessEngine#getCompiledRuntime
根据对象生成对应的javaCode,并写入到指定路径下,然后进行编译。编译使用的组件是org.eclipse.jdt.internal.compiler.Compiler
来编译的,FlowClassLoader指定路径进行类加载。AbstractProcessRuntime#executeProcessInstance
。执行流程,根据class来生成对应的实例,执行execute方法。