一、什么是acitiviti流程引擎
Activiti是一个面向业务人员、开发人员和系统管理员的轻量级工作流和业务流程管理(BPM)平台。它的核心是一个用于Java的超快速且坚如磐石的BPMN2过程引擎。它是开源的,并在Apache许可证下分发。Activiti在任何Java应用程序、服务器、集群或云中运行。它与Spring完美集成,非常轻量级,基于简单的概念。
二、如何使用
1.基本介绍

| 目录或文件 | 说明 |
|---|---|
| diagram-viewer | 图表查看器 |
| editor-app | 编辑器app |
| modeler.html | 流程图编辑页面 |
| index.html | 流程列表页面 |
swagger文档
- swagger访问地址: /swagger-ui/index.htm
- swagger配置:
// application.properties springdoc.swagger-ui.path=/swagger-ui.html

2. 创建模型
java代码:
/**
* 新建一个空模型
*
* @return
* @throws UnsupportedEncodingException
*/
@ApiOperation(value = "新建一个空模型")
@ApiParam(required = false)
@RequestMapping("/createNewEmptyModel")
public Map<String,Object> newModel(String name, String key) throws UnsupportedEncodingException {
RepositoryService repositoryService = processEngine.getRepositoryService();
//初始化一个空模型
Model model = repositoryService.newModel();
//设置一些默认信息,可以用参数接收
String description = "";
int revision = 1;
ObjectNode modelNode = objectMapper.createObjectNode();
modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);
model.setName(name);
model.setKey(key);
model.setMetaInfo(modelNode.toString());
repositoryService.saveModel(model);
String id = model.getId();
//完善ModelEditorSource
ObjectNode editorNode = objectMapper.createObjectNode();
editorNode.put("id", "canvas");
editorNode.put("resourceId", "canvas");
ObjectNode stencilSetNode = objectMapper.createObjectNode();
stencilSetNode.put("namespace",
"http://b3mn.org/stencilset/bpmn2.0#");
editorNode.put("stencilset", stencilSetNode);
repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
return success(model);
}
接口信息:
| 类型 | 值 |
|---|---|
| url | /models/createNewEmptyModel |
| method | GET |
| swagger url | /swagger-ui/index.html#/model-controller/newModel |
接口参数:
| 参数 | 说明 |
|---|---|
| name | 流程名称 |
| key | 流程key(需唯一) |
流程列表页面
创建完之后可以在流程列表页面看到新创建的流程,访问地址: /static/index.html:

3. 编辑流程
在流程列表页面点击"编辑流程"按钮:

设置流程图
点击右侧空白区域:

可以看到底部出现流程图设置栏,在这里进行一些流程图 必须的设置:
| 设置项 | 说明 |
|---|---|
| 流程唯一标识 | 设置流程图的 process_key , 最好同模型的 key 一致,因为部署流程时会从流程图的文件里读取这个值作为 process_key 而不是从模型的数据库记录里读取 |
| 名称 | 设置流程图的名称 |
开始事件
关于开始事件:
- 每一个流程都会有一个唯一的开始节点 开始事件,每一个流程创建后都从这个节点开始。
操作方法:
- 在左侧的菜单里,找到 开始事件 的下拉菜单里的 开始事件 (同一名字)按钮
- 鼠标左键长按点击按钮拖拽到右侧的空白区域

需要在底侧的编辑栏对 开始事件 节点做一些 设置 :
| 设置项 | 说明 |
|---|---|
| ID | 为节点设置一个ID,如 id_start |
| 名称 | 为节点设置一个名称,如 开始 |
| 执行监听器 | 链接 |
| 表单的标识Key | 链接 |
| 表单属性 | 链接 |
任务节点
关于任务节点:
- 在Activiti流程引擎中,活动(Activity)是指流程中的一个节点,代表了一个任务或者一组类似任务。活动可以是用户任务(User Task),服务任务(Service Task),脚本任务(Script Task),自动任务(Automatic Task)等等。在流程执行过程中,活动表示了一个节点的状态,即正在进行的任务或已经完成的任务。这里主要介绍用户任务(User Task)。
- 当一个流程执行到一个活动时,它会等待相应的事件,如用户完成任务或者收到服务任务响应。当事件发生后,流程就会继续执行下一个节点。Activiti引擎确保这些节点在正确的时间和顺序被执行,从而使流程在正确的时间内达到预期的结果。
- 总之,活动在Activiti中扮演着至关重要的角色,代表了流程中的一个节点和状态,通过正确的活动设置和执行,流程能够达到预期的效果。
操作方法:
- 在左侧的菜单里,找到 活动 的下拉菜单里的 人工服务 按钮
- 鼠标左键长按点击按钮拖拽到右侧的空白区域

| 设置项 | 说明 |
|---|---|
| ID | 为节点设置一个ID,如 id_node_a |
| 名称 | 为节点设置一个名称,如 A |
| 任务派遣 | 分配该节点的审批人或者分组,具体说明 见底下 |
| 执行监听器 | 链接 |
| 表单的标识Key | 链接 |
| 表单属性 | 链接 |
关于任务派遣:
- 任务派遣在Activiti中是一个常见的应用场景。在Activiti中,任务派遣可以通过用户任务的完成和代理人来实现。
- 用户任务是一个需要用户完成的工作流任务,当用户完成该任务后,工作流会自动进入下一个任务或任务节点。在Activiti中,通过设置任务的candidateUsers或candidateGroups属性来指定该任务被哪些用户或用户组拥有权限进行操作。完成用户任务的用户需要具有相应的权限才能操作该任务。
- 代理人则是一个具有代理权限的用户,代理人可以代替其他用户进行任务派遣或任务处理。在Activiti中,通过设置任务的assignee属性来指定该任务的代理人。代理人可以进行任务的处理、完成和删除等操作。
设置任务派遣:
- 在编辑区域底部设置栏里,找到 任务派遣 并单击
- 在弹出的弹框里设置Assignee、Candidate users、Candidate groups

方向箭头
关于方向箭头:
- 在Activiti中,方向箭头指示流程从一个任务或节点到另一个的流程。箭头将源任务或节点连接到目标任务或节点,表示流程从源流向目标。
- Activiti中有不同类型的方向箭头,每种箭头都有特定的含义。例如,带箭头的实线表示规则序列流,而带菱形箭头的虚线表示条件序列流。这里主要介绍带箭头的实线。
- 在使用该平台设计和创建工作流时,理解Activiti中不同方向箭头的含义非常重要。
操作方式:
- 鼠标左键点击不同的节点,会在节点周围出现一些按钮
- 长按鼠标左键点击点击 实心的箭头图标
- 拖拽 到 要连接的下一个节点,然后松开鼠标左键:


一个节点连接多个节点:

实线箭头设置弯曲点:
- 首先点击左上角倒数第二个蓝色按钮
- 然后再点击要调整的箭头
- 最后拖拽箭头的弯曲处调整箭头

设置路径选择条件表达式
- 点击箭头
- 在底部设置找到 跳转条件 栏, 填写为统一表达式语言 (UEL)
关于统一表达式语言 (UEL)
在 Activiti BPMN 引擎中,可以使用一种称为统一表达式语言 (UEL) 的表达式语言来定义条件和表达式。 Activiti 中条件的语法基于 Java EL 语法。下面是一些 Activiti 条件表达式的例子:
- ${task.priority > 50} (判断task.priority变量是否大于 50)
- ${task.assignee == "John Doe"} (判断task.assignee是否等于"John Doe")
- ${approvedByManager and (approvedByLegal or approvedByFinance)} (approvedByManager、approvedByLegal、approvedByFinance 都是布尔变量, 这里的是意思是 是否由 管理员审批(approvedByManager) 且 由 法务部门审批(approvedByLegal ) 或者 财务部门审批(approvedByFinance)至少其中的一个审批角色审批
在 统一表达式语言 (UEL) 语法中,表达式必须被包裹在 ${} 中, 可以使用 >、<、>=、<=、==、!= 等各种运算符和 and、or 和 not 等逻辑运算符来创建复杂的条件。此外,可以在表达式中使用 变量 和函数 来 创建动态条件。
在acitiviti 6.0.0版本中变量名采用带下划线小写的格式( 如 name_of_variable )无法正常识别变量,可能是基于Java EL 语法缘故因此需要遵循Java的变量命名规范即驼峰的命名方法(如 nameOfVariable )。
设置默认路线
- 点击箭头
- 在底部设置找到 默认路线 栏, 勾选
网关
在Activiti工作流中,单一网关和并行网关都是控制流程流转的关键点:
- 单一网关(Exclusive Gateway):它允许流程按照条件只选择一条流程线路进行流转。一般地,在网关的输出路线上会关联一个条件表达式。当流程执行到这个网关的时候,就会根据条件表达式的结果,自动选择到对应的输出路线流转。
- 并行网关(Parallel Gateway):它允许流程按照一组条件同时进行多条流程线路同时流转。当并行网关的输入路线的开始节点执行完成后,可以同时同时进入并行网关的所有输出路线所关联的任务节点,从而支持分支、合并、汇聚等复杂的流程模式。
在Activiti中使用这些网关非常简单。当您在设计流程时,选择一个网关类型并将其拖放到流程图中。然后,您可以通过连接线将任务节点与网关的输入和输出路线连接起来。在在输出路线上输入conditions表达式,以完成流程的逻辑分支或并行需求。详情可参考Activiti或BPMN文档。
操作方法
- 在左侧的菜单里,找到 网关 的下拉菜单里的 单一网关 按钮
- 鼠标左键长按点击按钮拖拽到右侧的空白区域
- 然后用箭头连接起来
如下图:

注意: 需要给网关的不同箭头设置跳转条件 ,且执行中不能 出现 同时满足两个路线 的情况,这是 单一网关 和 并行网关 中在使用中的区别 ,关于并行网关就不再示例说明
结束事件
关于结束事件:
- 每一个流程都会有一个唯一的结束节点 结束事件,当流程到达这一节点时整个流程就结束了。
操作方法:
- 在左侧的菜单里,找到 结束事件 的下拉菜单里的 结束事件 按钮
- 鼠标左键长按点击按钮拖拽到流程的结束位置
- 然后用箭头连接起来
保存
流程图编辑完成之后要保存修改:
- 点击左上角第一个蓝色按钮
- 在弹出的弹框里输入流程名称和描述
- 点击右下角 Save and close editor 或者 Save 按钮保存

4. 部署流程
关于部署流程:
- 流程图编辑保存之后,要使其生效还需要部署到流程引擎中。
- 不同的部署版本根据业务需求可能会有不同的key区分,比如对于key为 example_process_key的流程, 可以用example_process_key_deployed_v_01 , example_process_key_deployed_v_02来区分同一个流程的不同迭代版本,方便在业务代码里切换到不同版本的流程 。
操作方法:
- 访问
/static/index.html列表页面- 点击要部署的流程的那一行里的 部署流程 按钮

5. 新建任务
部署完流程之后,需要新建一个任务实例测试流程
接口信息:
| 类型 | 值 |
|---|---|
| url | /demo/newTask |
| method | GET |
| swagger url | /swagger-ui/index.html#/demo-controller/newTask |
接口参数:
| 参数 | 说明 |
|---|---|
| key | 流程图里设置的唯一标识 |
| businessId | 业务id,用来保存关联业务表的主键 |
后端代码:
@ApiOperation(value = "新任务")
@GetMapping("/newTask")
public Object newTask(String key,@RequestParam(defaultValue = "") String businessId)
{
ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
// 设置业务key
processInstanceBuilder.businessKey(businessId);
// 设置流程定义key
processInstanceBuilder.processDefinitionKey(key);
// 保存一些自定义的变量
Map<String,Object> variables =new HashMap<>();
variables.put("a","a1");
variables.put("b","b1");
processInstanceBuilder.variables(variables);
processInstanceBuilder.transientVariables(variables);
// 启动任务
processInstanceBuilder.start();
return success();
}
6. 查询任务
创建完任务后,查询待办任务
| 类型 | 值 |
|---|---|
| url | /demo/todo |
| method | GET |
| swagger url | /swagger-ui/index.html#/demo-controller/todo |
接口参数:
| 参数 | 说明 |
|---|---|
| processKey | 流程图里设置的唯一标识 |
| userId | 用户id,过滤 Candidate User 或 Assignee |
| role | 角色,过滤 Candidate Group |
| pageIndex | 分页索引,从1开始 |
| pageSize | 分页大小 |
当 查询条件过滤 Candidate User 或者 Candidate Group 时,生成的sql语句会带有 'assignee is null', 因此如果要以 Candidate User 或者 Candidate Group 为条件过滤时要确保 Assignee 不管是流程设置还是代码里不要设置值,这个是在这个demo所使用的
Activiti 6.0.0版本出现的问题,其他版本是否存在同样问题不确定。
接口返回示例:
{
"records": [
{
"taskId": "152507",
"taskDefinitionKey": "id_a",
"taskName": "A",
"businessId": null,
"processDefinitionId": "test-process:2:147514",
"taskLocalVariables": {},
"processVariables": {},
"processInstanceId": "152501",
"createTime": "2023-05-30 11:29:27",
"businessData": {
"id": "32382ced059d498491185137f728ef43",
"status": null,
"title": "faked"
}
}
],
"total": 1
}
后端代码:
@ApiOperation(value = "待办分页")
@GetMapping("/todo")
public PageModel todo(TodoReqModel todoReqModel) {
TaskService taskService = processEngine.getTaskService();
TaskQuery taskQuery = taskService.createTaskQuery();
taskQuery.active();
// 查询流程类型(通过processKey)
if(!StringUtils.isEmpty(todoReqModel.getProcessKey()))
{
taskQuery.processDefinitionKey(todoReqModel.getProcessKey());
}
// 查询分组
if(!StringUtils.isEmpty(todoReqModel.getRole()))
{
taskQuery.taskCandidateGroup(todoReqModel.getRole());
}
// 查询用户
if(!StringUtils.isEmpty(todoReqModel.getUserId()))
{
taskQuery.taskCandidateOrAssigned(todoReqModel.getUserId());
}
// 是否包含流程变量
// taskQuery.includeProcessVariables();
// 按创建时间倒序排序
taskQuery.orderByTaskCreateTime().desc();
Integer startAt = (todoReqModel.getPageIndex() - 1) * todoReqModel.getPageSize();
Integer endAt = todoReqModel.getPageIndex() * todoReqModel.getPageSize();
Long count = taskQuery.count();
List<Task> tasks = taskQuery.listPage(startAt, endAt);
List<TaskAndBusiness<DemoBusinessEntity>> records =new LinkedList<>();
tasks.forEach(task->{
TaskAndBusiness<DemoBusinessEntity> record =(TaskAndBusiness<DemoBusinessEntity>)TaskAndBusiness.makeFromTask(task);
record.setBusinessData(getDemoBusinessById(record.getBusinessId()));
records.add(record);
});
PageModel pageModel =new PageModel();
pageModel.setRecords(records);
pageModel.setTotal(count);
return pageModel;
}
7. 审批
接口信息:
| 类型 | 值 |
|---|---|
| url | /demo/complete |
| method | POST |
| swagger url | /swagger-ui/index.html#/demo-controller/complete |
接口参数:
| 参数 | 说明 |
|---|---|
| taskId | 任务id |
| params | 对象类型,用来提交自定义变量如: { key:val } , 在activiti 6.0.0 版本使用中存在用如 next_node 的命名规范的变量抛出异常,但是 驼峰 的写法( nextNode ) 可以正常传递变量 |
请求参数示例:
{
"taskId":"1",
"params":{
"alpha":"value of alpha",
"beta":"value of beta",
"nextNodeOfA":"B2",
"approved":false
}
}
后端代码:
@ApiOperation(value = "完成")
@PostMapping("/complete")
public Object complete(@RequestBody TaskCompleteModel taskCompleteModel) {
TaskService taskService = processEngine.getTaskService();
// 取出变量
Map<String, VariableInstance> variableInstances = taskService.getVariableInstances(taskCompleteModel.getTaskId());
// 取出变量
Map<String, Object> variables1 = taskService.getVariables(taskCompleteModel.getTaskId());
if(variables1!=null&& taskCompleteModel.getParams()!=null)
{
variables1.putAll(taskCompleteModel.getParams());
}
doSomethingBeforeTaskComplete(taskCompleteModel.getTaskId(),variables1);
taskService.complete(taskCompleteModel.getTaskId(),taskCompleteModel.getParams());
doSomethingAfterTaskComplete(taskCompleteModel.getTaskId(),variables1);
return success();
}
public void doSomethingBeforeTaskComplete(String taskId,Map<String, Object> variables)
{
log.info("doSomethingBeforeTaskComplete in supper");
}
public void doSomethingAfterTaskComplete(String taskId,Map<String, Object> variables)
{
log.info("doSomethingAfterTaskComplete in supper");
}
8. 事件处理
全局任务监听
可以创建一个 ActivitiListenerRegister 的服务类, 在应用启动时注册Bean时会实例化该类,因此可以在类的构造类或者 @PostConstruct 注解的方法里注册一个 ActivitiEventListener 事件监听器,Activiti会在事件发生时把事件分发到每个注册过的 ActivitiEventListener 里
ActivitiEventType 是一个枚举类,定义了不同的事件类型,这里只处理了 PROCESS_COMPLETED(流程完成) 的事件类型,可以在这时处理流程完成后的业务逻辑,比如修改业务表的状态等
@Slf4j
@Service
public class ActivitiListenerRegister {
private ProcessEngine processEngine;
private RuntimeService runtimeService;
private IProcessLeaveEventCompletelyHandler processLeaveCompletelyHandler;
public ActivitiListenerRegister(ProcessEngine processEngine, RuntimeService runtimeService, ProcessLeaveCompletelyHandler processLeaveCompletelyHandler) {
this.processEngine = processEngine;
this.runtimeService = runtimeService;
this.processLeaveCompletelyHandler = processLeaveCompletelyHandler;
}
@PostConstruct
public void init() {
runtimeService.addEventListener(new ActivitiEventListener() {
@SneakyThrows
@Override
public void onEvent(ActivitiEvent event) {
ActivitiEventType type = event.getType();
if (event.getType().equals(ActivitiEventType.TASK_COMPLETED)) {
log.info(" event type: " + ActivitiEventType.TASK_COMPLETED);
}
// 判断流程状态是否为已完成
if (event.getType() == ActivitiEventType.PROCESS_COMPLETED) {
String processInstanceId = event.getProcessInstanceId();
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceByProcessInstanceId(processInstanceId);
if (historicProcessInstance == null) {
throw new Exception(" processInstance not exists ");
}
// 获取到业务key
String businessKey = historicProcessInstance.getBusinessKey();
// 获取流程定义key(区分哪种流程)
String processDefinitionKey = historicProcessInstance.getProcessDefinitionKey();
switch (processDefinitionKey) {
// 处理离职流程
case ProcessDefinitionKeys.PROCESS_LEAVE:
processLeaveCompletelyHandler.handle(event, businessKey, processDefinitionKey);
break;
default:
break;
}
// Execute your code here
System.out.println("Process completed");
}
}
@Override
public boolean isFailOnException() {
return false;
}
});
}
/**
* 根据executionId获取单条Execution数据
* @param executionId
* @return
*/
protected Execution getExecutionById(String executionId) {
ExecutionQuery executionQuery = runtimeService.createExecutionQuery();
executionQuery.executionId(executionId);
Execution execution = executionQuery.singleResult();
return execution;
}
/**
* 根据processInstanceId获取单条HistoricProcessInstance
* @param processInstanceId
* @return HistoricProcessInstance
*/
protected HistoricProcessInstance getHistoricProcessInstanceByProcessInstanceId(String processInstanceId) {
HistoricProcessInstanceQuery historicProcessInstanceQuery = processEngine.getHistoryService().createHistoricProcessInstanceQuery();
historicProcessInstanceQuery.processInstanceId(processInstanceId);
HistoricProcessInstance historicProcessInstance = historicProcessInstanceQuery.singleResult();
return historicProcessInstance;
}
}
任务监听器
后端代码:
@Data
@Slf4j
public class ActivitiTaskEventListener implements TaskListener {
private Expression test;
/**
* 处理 任务监听器 通知的任务
* @param delegateTask
*/
@SneakyThrows
@Override
public void notify(DelegateTask delegateTask) {
// 获取自定义字段接收的值(如果有配置传值的话)
Object value = test.getValue(delegateTask);
String strValue = value == null ? null : value.toString();
// 获取事件名称
String eventName = delegateTask.getEventName();
switch (eventName) {
case BaseTaskListener.EVENTNAME_CREATE:
break;
case BaseTaskListener.EVENTNAME_ASSIGNMENT:
break;
case BaseTaskListener.EVENTNAME_COMPLETE:
break;
case BaseTaskListener.EVENTNAME_DELETE:
break;
default:
throw new Exception("未知的事件名称");
}
log.info("on notify with DelegateTask in ActivitiTaskCompleteEventListener");
}
}
关于任务监听器TaskListener :
- 在Activiti流程引擎里, 任务监听器 TaskListener 是用来处理不同类型的任务: create、complete、assignment、delete事件,分别代表创建、完成、分发、删除事件
配置任务监听器 TaskListener:
- 需要在后端创建一个自定义类实现org.activiti.engine.delegate.TaskListener 接口, 重写 notify(DelegateTask delegateTask)方法以处理事件
- 可以在自定义类里定义一个或者多个 org.activiti.engine.delegate.Expression 类型的自定义名称的字段,然后在流程编辑时设置对应的字段名称传字符串的值
- 点击某个需要配置任务监听器的节点
- 在底部找到 `任务监听器 或者 Task Listener 的栏,点击右侧弹出弹框
- 点击左边从上往下第一排蓝色按钮里的 + 按钮,右上角出现配置任务监听器的表单
- 参考下列表格配置任务监听器表单
| 字段 | 描述 |
|---|---|
| Event | 用来选择事件的类型,有create、complete、assignment、delete分别代表创建、完成、分发、删除事件,选择其中一种事件类型 |
| Class | 用来填写后端实现了 TaskListener 接口的自定义事件监听器,必须填写类的完整路径, 如 com.java.listener.ActivitiTaskEventListener
|
| Expression | 代替使用在监听器声明的 Class 字段的值, expression 被定义用来当事件触发的时候 估算值或调用方法(evaluated/invoked),如: <activiti:taskListener >expression="${myPojo.myMethod(execution.eventName)}" event="end" /><activiti:taskListener expression="${a == b}" event="end" />
|
| Delegate Expression | delegateExpression 允许指定一个表达式它解析一个实现了TaskListener 接口的bean对象,如: <activiti:taskListener event="start" >delegateExpression="${myTaskListenerBean}" />
|
配置自定义字段:
- 点击左上角要配置自定义字段的事件配置项
- 点击左边从上往下第二排蓝色按钮里的 + 按钮,右下角出现配置自定义字段的表单
- 参考下列表格配置表单
| 字段 | 描述 |
|---|---|
| Name | 用来填写自定义的字段名称, 该字段名称必须和对应的TaskListener里的字段名称匹配, 且类型为org.activiti.engine.delegate.Expression |
| String value | 用来填写传递到该字段的字符串类型的值 |
| Expression | 使用 expression 如: ${myVar}
|
| String | 在 Activiti 5.12 版本, 使用新的execution监听器类型org.activiti.engine.impl.bpmn.listener.ScriptExecutionListener 允许你为execution 监听事件执行一小块的逻辑脚本 |
org.activiti.engine.impl.bpmn.listener.ScriptExecutionListener
<activiti:executionListener event="start" class="org.activiti.engine.impl.bpmn.listener.ScriptExecutionListener" >
<activiti:field name="script">
<activiti:string>
def bar = "BAR"; // local variable
foo = "FOO"; // pushes variable to execution context
execution.setVariable("var1", "test"); // test access to execution instance
bar // implicit return value
</activiti:string>
</activiti:field>
<activiti:field name="language" stringValue="groovy" />
<activiti:field name="resultVariable" stringValue="myVar" />
</activiti:executionListener>
图片:

执行监听器
后端代码:
@Data
@Slf4j
public class ActivitiExecutionEventListener implements ExecutionListener {
private Expression test;
/**
* 处理 执行监听器 通知的任务
* @param delegateExecution
*/
@SneakyThrows
@Override
public void notify(DelegateExecution delegateExecution) {
Object value = test.getValue(delegateExecution);
String strValue = value == null ? null : value.toString();
String eventName = delegateExecution.getEventName();
switch (eventName) {
case BaseExecutionListener.EVENTNAME_START:
break;
case BaseExecutionListener.EVENTNAME_TAKE:
break;
case BaseExecutionListener.EVENTNAME_END:
break;
default:
throw new Exception("未知的事件名称");
}
log.info("on notify with DelegateExecution in ActivitiTaskCompleteEventListener");
}
}
关于执行监听器
ExecutionListener:
- 在Activiti流程引擎里, 任务监听器 ExecutionListener是用来处理任务start、end、take,即开始、结束、获取事件的
配置执行监听器
ExecutionListener:
- 需要在后端创建一个自定义类实现
org.activiti.engine.delegate.ExecutionListener接口, 重写notify(DelegateExecution delegateExecution)方法- 可以在自定义类里定义一个或者多个 org.activiti.engine.delegate.Expression 类型的自定义名称的字段,然后在流程编辑时设置对应的字段名称传字符串的值。
- 点击某个需要配置任务监听器的节点
- 在底部找到 执行监听器 或者 Execution Listener 的栏,点击右侧弹出弹框
org.activiti.engine.delegate.Expression 类型的自定义名称的字段,然后在流程编辑时设置对应的字段名称传字符串的值。- 点击左边从上往下第一排蓝色按钮里的 + 按钮,右上角出现配置任务监听器的表单
- 参考下方表格配置表单
| 字段 | 描述 |
|---|---|
| Event | 用来选择事件的类型,有create、end、take分别代表创建、结束、获取事件,选择其中一种事件类型 |
| Class | 用来填写后端实现了 ExecutionListener 接口的自定义事件监听器,必须填写类的完整路径, 如 com.java.listener.ActivitiExecutionEventListener |
| Expression | 代替使用在监听器声明的 Class的值, expression 被定义用来当事件触发的时候 估算值或调用方法(evaluated/invoked),如: <activiti:executionListener >expression="${myPojo.myMethod(execution.eventName)}" event="end" /><activiti:executionListener expression="${a == b}" event="end" />
|
| Delegate Expression | delegateExpression 允许指定一个表达式它解析一个实现了ExecutionListener 接口的bean对象,如: <activiti:executionListener event="start" >delegateExpression="${myExecutionListenerBean}" />
|
配置自定义字段:
- 点击左上角要配置自定义字段的事件配置项
- 点击左边从上往下第二排蓝色按钮里的 + 按钮,右下角出现配置自定义字段的表单
- 参考下列表格配置表单
| 字段 | 描述 |
|---|---|
| Name | 用来填写自定义的字段名称, 该字段名称必须和对应的TaskListener里的字段名称匹配, 且类型为org.activiti.engine.delegate.Expression |
| String value | 用来填写传递到该字段的字符串类型的值 |
| Expression | 使用 expression 如: ${myVar}
|
| String | 在 Activiti 5.12 版本, 使用新的execution监听器类型org.activiti.engine.impl.bpmn.listener.ScriptExecutionListener 允许你为execution 监听事件执行一小块的逻辑脚本 |
