Activiti 简介
Java 通用型工作流引擎:Activiti。
源代码:https://github.com/Activiti/Activiti
Activiti is the leading lightweight, java-centric open-source BPMN engine supporting real-world process automation needs.
Activiti 项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准。
Activiti 是一种轻量级,可嵌入的BPM引擎,而且还设计适用于可扩展的云架构。 Activiti将提供宽松的 Apache 许可2.0,同时促进Activiti BPM引擎和BPMN 2.0的匹配。
Activiti 的核心服务组件
1.RepositoryService:提供一系列管理流程部署和流程定义的API。
2.RuntimeService:在流程运行时对流程实例进行管理与控制。
3.TaskService:对流程任务进行管理,例如任务提醒、任务完成和创建任务等。
4.IdentityService:提供对流程角色数据进行管理的API,这些角色数据包括用户组、用户及它们之间的关系。
5.ManagementService:提供对流程引擎进行管理和维护的服务。
6.HistoryService:对流程的历史数据进行操作,包括查询、删除这些历史数据。
7.FormService:表单服务。
Activiti应用场景:
多人协作的(或者需要动态变动)的业务流程场景。
业务流程模型 BPMN xml 配置文件
一个xml文件,activiti去解析这个文件,了解我们到底想干什么事。
test01.bpmn20.xml 实例:
其中,activiti:class="com.example.actividemo.ServiceTask1"
和 activiti:class="com.example.actividemo.ServiceTask2"
对应到代码里:
package com.example.actividemo;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
public class ServiceTask1 implements JavaDelegate {
//流程变量
private Expression text1;
//重写委托的提交方法
@Override
public void execute(DelegateExecution execution) {
System.out.println("serviceTask1 已经执行已经执行!");
String value1 = (String) text1.getValue(execution);
System.out.println(value1);
execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
}
}
package com.example.actividemo;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
public class ServiceTask2 implements JavaDelegate {
//流程变量
private Expression text2;
//重写委托的提交方法
@Override
public void execute(DelegateExecution execution) {
System.out.println("serviceTask2 已经执行已经执行!");
String value1 = (String) text2.getValue(execution);
System.out.println(value1);
execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
}
}
Spring Boot 集成 Activiti 项目实战
创建 Spring Boot 工程,目录结构如下:
.
├── HELP.md
├── activi-demo.iml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── actividemo
│ │ ├── ActivitiController.java
│ │ ├── ActivityConsumerService.java
│ │ ├── ActivityConsumerServiceImpl.java
│ │ ├── Application.java
│ │ ├── ServiceTask1.java
│ │ └── ServiceTask2.java
│ └── resources
│ ├── application.properties
│ ├── static
│ ├── templates
│ └── test01.bpmn20.xml
└── test
└── java
└── com
└── example
└── actividemo
└── ApplicationTests.java
14 directories, 14 files
源代码如下:
ActivitiController
package com.example.actividemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/activiti")
public class ActivitiController {
@Autowired
private ActivityConsumerService activityConsumerService;
/**
* 注册流程
*
* @return
*/
@RequestMapping("/createDeployment")
public Boolean createDeployment() {
return activityConsumerService.createDeployment();
}
/**
* 启动流程
*
* @return
*/
@RequestMapping("/startActivityDemo")
public Boolean startActivityDemo() {
return activityConsumerService.startActivityDemo("test01");
}
/**
* 获取待办
*
* @return
*/
@RequestMapping("/getTaskList")
public List getTaskList() {
return activityConsumerService.getTaskList();
}
/**
* 提交
*
* @param taskId
* @return
*/
@RequestMapping("/complete")
public boolean complete(String taskId) {
return activityConsumerService.complete(taskId);
}
/**
* 根据流程id直接结束流程
*
* @return
* @paramru
*/
@RequestMapping("/deleteProcessInstance")
public boolean deleteProcessInstance(String runId) {
return activityConsumerService.deleteProcessInstance(runId);
}
}
ActivityConsumerService
package com.example.actividemo;
import java.util.List;
public interface ActivityConsumerService {
boolean createDeployment();
boolean startActivityDemo(String key);
List getTaskList();
boolean complete(String taskId);
boolean deleteProcessInstance(String runId);
}
ActivityConsumerServiceImpl
package com.example.actividemo;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("activityService")
public class ActivityConsumerServiceImpl implements ActivityConsumerService {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private HistoryService historyService;
@Autowired
private RepositoryService repositoryService;
/**
* 注册一个流程
*
* @return
*/
@Override
public boolean createDeployment() {
DeploymentBuilder builder = repositoryService.createDeployment();
builder.addClasspathResource("test01.bpmn20.xml");
builder.deploy();
return true;
}
/**
* 查询待办
*
* @return
*/
public List getTaskList() {
return historyService.createHistoricActivityInstanceQuery().list();
}
/**
* 根据流程key开启一个流程
*
* @param key
* @return
*/
@Override
public boolean startActivityDemo(String key) {
ProcessInstance test01 = runtimeService.startProcessInstanceByKey(key);
String id = test01.getId();
System.out.println("流程id=" + id);
return true;
}
/**
* 根据任务id提交任务
*
* @param taskId
* @return
*/
@Override
public boolean complete(String taskId) {
taskService.complete(taskId);
return true;
}
/**
* 根据流程id直接结束流程
*
* @param runId
* @return
*/
@Override
public boolean deleteProcessInstance(String runId) {
runtimeService.deleteProcessInstance(runId, "结束");
return true;
}
}
Application
package com.example.actividemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(exclude = {
org.activiti.spring.boot.SecurityAutoConfiguration.class
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
ServiceTask1 、ServiceTask2
package com.example.actividemo;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
public class ServiceTask1 implements JavaDelegate {
//流程变量
private Expression text1;
//重写委托的提交方法
@Override
public void execute(DelegateExecution execution) {
System.out.println("serviceTask1 已经执行已经执行!");
String value1 = (String) text1.getValue(execution);
System.out.println(value1);
execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
}
}
package com.example.actividemo;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
public class ServiceTask2 implements JavaDelegate {
//流程变量
private Expression text2;
//重写委托的提交方法
@Override
public void execute(DelegateExecution execution) {
System.out.println("serviceTask2 已经执行已经执行!");
String value1 = (String) text2.getValue(execution);
System.out.println(value1);
execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
}
}
项目配置文件 application.properties
server.port=8080
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/activi_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=88888888
spring.activiti.check-process-definitions=false
spring.activiti.process-definition-location-prefix=classpath:*
spring.activiti.process-definition-location-suffixes=.bpmn20.xml
Maven 项目配置文件 pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.1
com.example
activi-demo
0.0.1-SNAPSHOT
activi-demo
Demo project for Spring Boot
1.8
6.0.0
org.activiti
activiti-engine
${activiti.version}
org.activiti
activiti-spring
${activiti.version}
org.activiti
activiti-spring-boot-starter-basic
${activiti.version}
org.activiti
activiti-common-rest
${activiti.version}
org.activiti
activiti-modeler
5.22.0
spring-beans
org.springframework
spring-context
org.springframework
spring-core
org.springframework
spring-tx
org.springframework
spring-web
org.springframework
spring-security-config
org.springframework.security
spring-security-core
org.springframework.security
spring-security-crypto
org.springframework.security
spring-security-web
org.springframework.security
spring-webmvc
org.springframework
activation
javax.activation
commons-io
commons-io
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-maven-plugin
运行测试
先部署任务:http://127.0.0.1:8080/activiti/createDeployment
然后启动工作流实例:http://127.0.0.1:8080/activiti/startActivityDemo
运行输出:
serviceTask1 已经执行已经执行!
test1
serviceTask2 已经执行已经执行!
test2
流程id=7501
查看历史流程:http://127.0.0.1:8080/activiti/getTaskList
[
{
"id": "10003",
"processInstanceId": "10001",
"processDefinitionId": "test01:3:5044",
"startTime": "2021-06-13T07:20:19.009+00:00",
"endTime": "2021-06-13T07:20:19.010+00:00",
"durationInMillis": 1,
"deleteReason": null,
"activityId": "sid-d0c54d06-2073-4018-8381-e5e43f1b5578",
"activityName": "Start",
"activityType": "startEvent",
"executionId": "10002",
"assignee": null,
"taskId": null,
"calledProcessInstanceId": null,
"tenantId": "",
"persistentState": {
"executionId": "10002",
"durationInMillis": 1,
"endTime": "2021-06-13T07:20:19.010+00:00",
"assignee": null,
"deleteReason": null
},
"time": "2021-06-13T07:20:19.009+00:00",
"inserted": false,
"deleted": false,
"updated": false
},
...
,
{
"id": "7514",
"processInstanceId": "7508",
"processDefinitionId": "test01:3:5044",
"startTime": "2021-06-13T06:47:16.733+00:00",
"endTime": "2021-06-13T06:47:16.733+00:00",
"durationInMillis": 0,
"deleteReason": null,
"activityId": "sid-665b6b28-9b81-4ab7-ba77-6eb50da3c810",
"activityName": "End",
"activityType": "endEvent",
"executionId": "7509",
"assignee": null,
"taskId": null,
"calledProcessInstanceId": null,
"tenantId": "",
"persistentState": {
"executionId": "7509",
"durationInMillis": 0,
"endTime": "2021-06-13T06:47:16.733+00:00",
"assignee": null,
"deleteReason": null
},
"time": "2021-06-13T06:47:16.733+00:00",
"inserted": false,
"deleted": false,
"updated": false
}
]
工作流的数据库表数据:
数据库共28张表。一些比较重要的表有:
- act_ru_execution 执行对象表
- act_ru_task 用户任务表
- act_hi_actinst 活动节点历史表
- act_hi_procinst 流程实例历史表
- act_hi_taskinst 历史任务表
参考资料
https://www.cnblogs.com/qq376324789/p/12023530.htmlhttps://www.jianshu.com/p/972613558ba1