简介
Flowable是一款基于Java的开源业务流程引擎,核心BPMN流程引擎,附带DMN决策表和CMMN案例管理引擎。

与Spring完美集成,本身自带REST API。

目前最新版是 Flowable 6.4.0


官网地址: https://www.flowable.org/

github地址: https://github.com/flowable

集成到springboot
1. MAVEN依赖
使用的springboot版本 2.0.5.RELEASE

flowable提供了与springboot集成的starter包,只需要引入到pom文件里,

一定要注意引入自己需要的就行了!

starter 详细
flowable-spring-boot-starter-cmmn 包含CMMN案例管理引擎
flowable-spring-boot-starter-cmmn-rest 同上,另外包含REST API
flowable-spring-boot-starter-dmn 包含DMN决策表引擎
flowable-spring-boot-starter-dmn-rest 同上,另外包含REST API
flowable-spring-boot-starter-process 包含业务流程引擎,会自动扫描 resources/processes
下的 .bpmn20
、 .bpmn20.xml
文件并部署
flowable-spring-boot-starter-process-rest 同上,另外包含REST API
flowable-spring-boot-starter 包含flowable全家桶(Process流程引擎, CMMN案例管理引擎, DMN决策表引擎, Form表单, Content 以及 IDM用户认证)
flowable-spring-boot-starter-rest 同上,另外包含REST API
flowable-spring-boot-starter-actuator Spring启动的一些依赖
在mvnrepository里有一个 flowable-spring-boot-starter-basic
,这个其实就是 flowable-spring-boot-starter-process
,对,是改名的锅。

flowable-spring-boot-starter-actuator
好像没什么用。

这次引入的maven依赖:

org.flowable
flowable-spring-boot-starter-process-rest
6.4.0


org.flowable
flowable-spring-boot-starter-actuator
6.4.0



org.springframework.boot
spring-boot-starter-web



mysql
mysql-connector-java



com.alibaba
druid
${druid.version}

2. 数据源配置
由于使用的是阿里巴巴的druid连接池,注册 DruidDataSource
就行了,详情参考 DruidDataSource配置

第一次使用会创建表到数据库里,如果遇到 liquibase.exception.LockException
,需要手动把表名后缀为 databasechangeloglock
的字段 LOCKED
里的值由1改成0(原因可能是多次更换flowable依赖)。

  1. 流程设计器、用户和流程管理系统
    首先下载 tomcat-flowable-6.4.0.zip

在 webapps
目录里有四个 war

flowable-idm:用户管理、授权
flowable-admin:实例、任务管理
flowable-modeler:设计器
flowable-task:个人任务管理
这些 war
包都能直接使用 java -jar flowable-[项目].war
启动。

注意: flowable-idm
也用于其他项目的登陆授权。

这时还不能启动,需要修改一些配置:

依次解压,打开其中的 WEB-INFclasses
目录,修改 flowable-default.properties
文件里的数据库连接信息(
spring.datasource.driver-class-name

spring.datasource.url

spring.datasource.username

spring.datasource.password
),之后重命名文件为 application.properties
往 WEB-INFlib
里加入数据库驱动文件,我的是 mysql-connector-java-5.1.47.jar
最后使用 /tomcat-flowable/bin/startup.bat
启动,默认端口 8080
,访问地址: 实例管理
、 设计器
、 用户管理
、 个人任务

默认账号:admin
默认密码:test
具体流程设计可以参考 官方文档

  1. 使用方法
    这次使用的是 ProcessEngine

ProcessEngine
里常用的几个:

RepositoryService
RuntimeService
IdentityService
TaskService
HistoryService
在 ProcessEngineServicesAutoConfiguration
里已经把这些类注册到Spring里,使用的时候这样声明就行:

@Autowired
private RepositoryService repositoryService;
部署流程
Deployment deployment = repositoryService.createDeployment()
// 项目路径
.addClasspathResource(classpath)
// 业务归档(BAR)文件
// .addZipInputStream(inputStream)
// 字节流
// .addInputStream(in)
// 文本
// .addString(xml)
.deploy();

开始流程(创建流程实例)
try {
// 设置发起人
identityService.setAuthenticatedUserId(user.getId());
// processDefinitionKey 流程id
// businessKey 自定义编号,可以放业务编号
// variables 自定义参数
runtimeService.startProcessInstanceByKey(key, user.getId(), vars);
} finally {
// 单线程需要这样处理,原文如下:
// Passes the authenticated user id for this particular thread. All service method (from any service) invocations done by the same thread will have access to this authenticatedUserId.
identityService.setAuthenticatedUserId(null);
}

处理任务
taskService.complete(taskId, params);
获取历史流程实例
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
// query.unfinished() 未结束的流程实例
// query.finished() 已结束的流程实例
// query.variableValueEquals("UserId", user.getId()) 查询实例变量
// query.startedBy(user.getId()) 由谁发起,需要开始的时候设置identityService.setAuthenticatedUserId(user.getId())
// 按照开始时间倒序
List list = query.orderByProcessInstanceStartTime().desc().list()

获取历史流程实例变量
Map params = historyService.createHistoricVariableInstanceQuery()
// 实例id
.processInstanceId(id)
.list().stream()
// 组装成Map
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue));

获取进行中的流程实例任务变量(不能获取已结束的)
TaskQuery query = taskService.createTaskQuery();
Task task = query.taskId(taskId).singleResult();
Map params = runtimeService.getVariables(task.getExecutionId());

获取历史流程实例活动
List activities = historyService.createHistoricActivityInstanceQuery()
// 实例id
.processInstanceId(id)
.list();

通用查询流程实例任务
// 需要事先指定是否正在进行
`TaskInfoQueryWrapper taskInfoQueryWrapper = runtime ? new TaskInfoQueryWrapper(taskService.createTaskQuery())
: new TaskInfoQueryWrapper(historyService.createHistoricTaskInstanceQuery());

TaskInfoQuery query = taskInfoQueryWrapper.getTaskInfoQuery();
List tasks = query.list();`