什么是flowable:
基于actives发展而来的一款开源流程引擎工具
入门参考:flowable官方文档
使用流程:
- 引入jar包(此次仅演示springboot项目中)
- 绘制bpmn流程图,生成xml文件或直接编写流程的xml文件
- 根据编写的流程来编写代码
jar包的引入:
<!-- flowable -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.3.0</version>
</dependency>
注意:在实际应用中,我们常常会在代码中使用到mybatis,直接这样引入之后会发现报错!错误的原因是因为,flowable 集成是也会引入 mybatis jar包,导致jar冲突,所以解决方案是引入 flowable 时,排除 mybatis,所以依赖应该这样引入:
<!-- flowable -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.3.0</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
bpmn流程
xml文件的编写:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.flowable.org/processdef">
<process id="fixBug" name="fix-bug" isExecutable="true">
<!-- 流程开始 -->
<startEvent id="startEvent"/>
<sequenceFlow id="start" sourceRef="startEvent" targetRef="createTask"/>
<userTask id="createTask" name="创建任务" flowable:assignee="${employeeId}"/>
<sequenceFlow sourceRef="createTask" targetRef="dealTask"/>
<!--
assignee 受让人
candidateGroups 候选组
candidateUsers 候选人
-->
<userTask id="dealTask" name="程序员处理或忽略任务"/>
<sequenceFlow sourceRef="dealTask" targetRef="isRightDeal"/>
<!---->
<userTask id="isRightDeal" name="管理者判断是否正确处理"/>
<sequenceFlow sourceRef="isRightDeal" targetRef="decision"/>
<!-- 判断是否已正确处理 -->
<exclusiveGateway id="decision"/>
<sequenceFlow sourceRef="decision" targetRef="right">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[
${right}
]]>
</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="decision" targetRef="wrong">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[
${!right}
]]>
</conditionExpression>
</sequenceFlow>
<userTask id="wrong" name="没有正确处理任务"/>
<sequenceFlow sourceRef="wrong" targetRef="dealTask"/>
<serviceTask id="right" name="已正确处理任务" flowable:class="com.example.project.service.RightDelegate"/>
<sequenceFlow sourceRef="right" targetRef="compliant"/>
<endEvent id="compliant"/>
</process>
</definitions>
definitions
标签是固定格式,复制粘贴上即可;process
标签开始编写流程,其中id属性较为重要,后面需要用来创建任务。流程的开始由startEvent
标签指定,sequenceFlow
标签可以理解为顺序流,使用sourceRef
属性和targetRef
属性来指定流的来源和目的地。userTask
是用户任务,相当于由用户操作完成(complete),当受让人(flowable:assignee
)在代码中调用了complete
方法后,这个userTask接入,流向target
所指的任务。exclusiveGateway
标签是一个网关,用于作条件判断,如以上代码中判断的字段是right
。serviceTask
可理解为系统任务,即根据系统代码自行根据编写的规则完成,不需要等待用户操作,如以上代码中flowable:class
属性指向了RightDelegate
这个类,这个类实现了java的中的委托(delegate)。重写了execute
方法,系统走到serviceTask
时会自动执行execute
中的方法,然后自动complete任务进入下一步。endEvent
标签指示流程结束。
代码的编写:
在springboot的项目中,引入了flowable之后,在项目启动的时候,flowable回去检测数据库是否存在flowable的60张表,如果存在则什么也不执行,如果不存在则会自动创建表,需要注意的是,flowable自动创建表的时候会限制当前数据库中不能存在任何表,也就是需要在一个空的数据库中才能成功的自动创建,所以如果我们需要让flowable的表与其它表在同一个库中的时候,我们可以先让flowable在一个空的数据库中创建完成后,我们再手动导入目标数据库即可。
此处由于表过多,而且名称也很像,对各个表存储的数据信息我们就参考别人的笔记就可以:flowable表结构
flowable被加载进spring的容器之后,会向外提供一些service,我们在实际的编码中也就是根据它提供的service来对流程进行控制的,这里我们使用自动装配来引入service:
@Autowired
private RepositoryService repositoryService;
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private HistoryService historyService;
@Autowired
private ManagementService managementService;
@Autowired
private FormService formService;
@Autowired
private IdentityService identityService;
几个service的不同
RepositoryService:
- 查询引擎已知的部署和流程定义。
- 挂起并激活整个部署或特定过程定义。挂起表示无法对其进行进一步的操作,而激活则相反,并且可以再次启用操作。
- 检索各种资源,例如引擎自动生成的包含在部署或流程图中的文件。
- 检索流程定义的POJO版本,该版本可用于使用Java而不是XML对流程进行内部检查。
RuntimeService:- 处理启动流程定义的新流程实例(根据流程定义启动一个流程)
- 获取和存储过程变量
- 查询流程实例和当前执行位置
TaskService:
- 查询分配给用户或组的任务
- 创建新的独立任务。这些是与流程实例无关的任务。
- 操纵任务分配给哪个用户或该任务涉及某种用户。
- 声明并完成任务。声明意味着某人决定担任该任务的受让人,这意味着该用户将完成任务。完成意味着“完成任务的工作”。通常,这是一种形式的填充。
IdentityService:
- 组和用户的管理(创建,更新,删除,查询等)
FormService:
- 表单服务(具体怎么使用不清楚)
HistoryService:
- 查询流程的历史数据
ManagementService:
- 查询数据库表信息和表的元数据
- 管理各种 jobs 任务,例如计时器,异步,挂起/激活等等
参考文档:flowable API
JavaDelegate.java
public class RightDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
//TODO 任务处理完成且审核通过,进行消息通知
}
}