簡介
Flowable是一款基於Java的開源業務流程引擎,核心BPMN流程引擎,附帶DMN決策表和CMMN案例管理引擎。
與Spring完美集成,本身自帶REST API。
目前最新版是Flowable 6.4.0(2018年10月26日)
官網地址:https://www.flowable.org/
github地址:https://github.com/flowable
個人demo地址:https://github.com/xwbz2017/flowable-demo
集成到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依賴:
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-process-rest</artifactId>
<version>6.4.0</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-actuator</artifactId>
<version>6.4.0</version>
</dependency>
<!------------------------------- 其他 --------------------------------->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mysql數據庫驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
2. 數據源配置
由於使用的是阿里巴巴的druid連接池,注冊DruidDataSource
就行了,詳情參考DruidDataSource配置。
第一次使用會創建表到數據庫里,如果遇到liquibase.exception.LockException
,需要手動把表名后綴為databasechangeloglock
的字段LOCKED
里的值由1改成0(原因可能是多次更換flowable依賴)。
3. 流程設計器、用戶和流程管理系統
在webapps
目錄里有四個war
包
- flowable-idm:用戶管理、授權
- flowable-admin:實例、任務管理
- flowable-modeler:設計器
- flowable-task:個人任務管理
這些war
包都能直接使用java -jar flowable-[項目].war
啟動。
注意:flowable-idm
也用於其他項目的登陸授權。
這時還不能啟動,需要修改一些配置:
- 依次解壓,打開其中的
WEB-INF\classes
目錄,修改flowable-default.properties
文件里的數據庫連接信息(
spring.datasource.driver-class-name
、
spring.datasource.url
、
spring.datasource.username
、
spring.datasource.password
),之后重命名文件為application.properties
- 往
WEB-INF\lib
里加入數據庫驅動文件,我的是mysql-connector-java-5.1.47.jar
最后使用/tomcat-flowable/bin/startup.bat
啟動,默認端口8080
,訪問地址:實例管理、設計器、用戶管理、個人任務。
- 默認賬號:admin
- 默認密碼:test
具體流程設計可以參考官方文檔
4. 使用方法
這次使用的是
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<HistoricProcessInstance> list = query.orderByProcessInstanceStartTime().desc().list()
獲取歷史流程實例變量
Map<String, Object> 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<String, Object> params = runtimeService.getVariables(task.getExecutionId());
獲取歷史流程實例活動
List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery()
// 實例id
.processInstanceId(id)
.list();
通用查詢流程實例任務
// 需要事先指定是否正在進行
TaskInfoQueryWrapper taskInfoQueryWrapper = runtime ? new TaskInfoQueryWrapper(taskService.createTaskQuery())
: new TaskInfoQueryWrapper(historyService.createHistoricTaskInstanceQuery());
TaskInfoQuery query = taskInfoQueryWrapper.getTaskInfoQuery();
List<TaskInfo> tasks = query.list();