文章目录
- 一、全局监听器
- 事件类型
- 配置方式(选)
- 日志监听器
- 代码实现
- xml文件
- 创建全局监听器
- 全局配置类
- 测试流程
- 部署流程
- 启动流程
一、全局监听器
它是引擎范围的事件监听器,可以捕获所有的Activiti事件。
事件类型
ActivitiEventType
枚举类中包含全部事件类型
配置方式(选)
-
spring bean配置
-
全局配置类设置(config.setEventListeners())
config.setEventListeners(Collections.singletonList(new MyGlobalEventListener()));
-
启动流程动态添加并且可以指定要监听的事件类型(推荐)
runtimeService.addEventListener(new MyGlobalEventListener(), ActivitiEventType.TASK_CREATED, ActivitiEventType.TASK_ASSIGNED, ActivitiEventType.TASK_COMPLETED);
-
class
-
expression
-
delegateExpression
日志监听器
全局配置类开启:config.setEnableDatabaseEventLogging(true);
开启后可以在 act_evt_log
表中看到相关的日志记录。
代码实现
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:activiti="http://activiti.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.activiti.org/processdef">
<process id="global-listener" name="全局事件监听器" isExecutable="true">
<documentation>测试全局事件监听器</documentation>
<extensionElements>
<!-- 需要高版本的插件才能不爆红 支持class expression delegateExpression 配置方式 -->
<!-- <activiti:eventListener entityType="task" delegateExpression="${myGlobalEventListener}"/>-->
</extensionElements>
<startEvent id="sid-30244641-2a1c-43e5-af5b-e77db43488bf" name="开始">
<documentation>开始了</documentation>
</startEvent>
<userTask id="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" name="节点1"
activiti:assignee="${applyUserId}" activiti:candidateUsers="${candidateUsers}" activiti:candidateGroups="${candidateGroups}">
<documentation>任务节点1</documentation>
</userTask>
<sequenceFlow id="sid-1af5e647-b03c-4b12-807d-4171dfdf7ae9" sourceRef="sid-30244641-2a1c-43e5-af5b-e77db43488bf" targetRef="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" name="顺序流1">
<documentation>顺序流1了</documentation>
</sequenceFlow>
<userTask id="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0" name="节点2">
<documentation>任务节点2</documentation>
</userTask>
<sequenceFlow id="sid-300ac02e-dc56-4988-bdd4-fd94a5bb71f7" sourceRef="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec" targetRef="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0" name="顺序流2">
<documentation>顺序流2了</documentation>
</sequenceFlow>
<endEvent id="sid-ace3a923-023c-4226-875c-2a0a30cc1c50" name="结束">
<documentation>结束了</documentation>
</endEvent>
<sequenceFlow id="sid-dbf73610-a8b4-4149-828e-4f5bc252c80d" sourceRef="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0" targetRef="sid-ace3a923-023c-4226-875c-2a0a30cc1c50" name="顺序流3">
<documentation>顺序流3了</documentation>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_execution-listener">
<bpmndi:BPMNPlane bpmnElement="global-listener" id="BPMNPlane_execution-listener">
<bpmndi:BPMNShape id="shape-d4dd6424-1316-4c10-a8f9-f3c501cd4073" bpmnElement="sid-30244641-2a1c-43e5-af5b-e77db43488bf">
<omgdc:Bounds x="-442.5" y="-6.75" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-bcd8743b-6857-42d1-bc71-bd3bb6eed795" bpmnElement="sid-9e62413f-e04f-4c81-8d0c-e73f17e125ec">
<omgdc:Bounds x="-388.0" y="-31.75" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-d562b253-050f-4617-bbad-2e16950c15e4" bpmnElement="sid-1af5e647-b03c-4b12-807d-4171dfdf7ae9">
<omgdi:waypoint x="-412.5" y="8.25"/>
<omgdi:waypoint x="-388.0" y="8.25"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-cd7c00d6-f5f0-4afe-867c-6f576efc286d" bpmnElement="sid-d903cb09-56c2-4cfe-bd05-5ba0699539d0">
<omgdc:Bounds x="-259.0" y="-31.75" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-44a5c4d2-2ab7-48f1-adc7-c7a7a099800c" bpmnElement="sid-300ac02e-dc56-4988-bdd4-fd94a5bb71f7">
<omgdi:waypoint x="-288.0" y="8.25"/>
<omgdi:waypoint x="-259.0" y="8.25"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="shape-05cc9b19-8019-471d-b31c-bb41c42e3529" bpmnElement="sid-ace3a923-023c-4226-875c-2a0a30cc1c50">
<omgdc:Bounds x="-123.0" y="-6.75" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-923723d0-33e3-4a62-bed9-bb16d4c9b175" bpmnElement="sid-dbf73610-a8b4-4149-828e-4f5bc252c80d">
<omgdi:waypoint x="-159.0" y="8.25"/>
<omgdi:waypoint x="-123.0" y="8.25"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
创建全局监听器
@Component("myGlobalEventListener")
public class MyGlobalEventListener implements ActivitiEventListener {
@Override
public void onEvent(ActivitiEvent event) {
System.out.println("========================MyGlobalEventListener========================");
switch (event.getType()) {
case TASK_CREATED:
this.taskCreate(event);
break;
case TASK_ASSIGNED:
this.taskAssigned(event);
break;
case TASK_COMPLETED:
this.taskComplete(event);
break;
default:
System.out.println("Event received: " + event.getType());
}
}
/**
* 上面的 onEvent 方法抛出异常的后续处理动作
* false :表示忽略onEvent()方法方法中抛出的异常
* true :表示onEvent()方法中抛出的异常继续向上传播,导致当前操作失败
*/
@Override
public boolean isFailOnException() {
return false;
}
private void taskCreate(ActivitiEvent event) {
System.out.println("===================任务创建事件===================");
ActivitiEntityEventImpl activitiEntityEvent = (ActivitiEntityEventImpl) event;
TaskEntity taskEntity = (TaskEntity) activitiEntityEvent.getEntity();
System.out.println("taskEntity.getId() = " + taskEntity.getId());
System.out.println("taskEntity.getName() = " + taskEntity.getName());
System.out.println("taskEntity.getAssignee() = " + taskEntity.getAssignee());
System.out.println("taskEntity.getIdentityLinks() = " + taskEntity.getIdentityLinks());
System.out.println("taskEntity.getVariables() = " + taskEntity.getVariables());
}
private void taskAssigned(ActivitiEvent event) {
System.out.println("===================任务分配事件===================");
ActivitiEntityEventImpl activitiEntityEvent = (ActivitiEntityEventImpl) event;
TaskEntity taskEntity = (TaskEntity) activitiEntityEvent.getEntity();
System.out.println("taskEntity.getId() = " + taskEntity.getId());
System.out.println("taskEntity.getName() = " + taskEntity.getName());
System.out.println("taskEntity.getAssignee() = " + taskEntity.getAssignee());
System.out.println("taskEntity.getIdentityLinks() = " + taskEntity.getIdentityLinks());
System.out.println("taskEntity.getVariables() = " + taskEntity.getVariables());
}
private void taskComplete(ActivitiEvent event) {
System.out.println("===================任务完成事件===================");
ActivitiEntityEventImpl activitiEntityEvent = (ActivitiEntityEventImpl) event;
TaskEntity taskEntity = (TaskEntity) activitiEntityEvent.getEntity();
System.out.println("taskEntity.getId() = " + taskEntity.getId());
System.out.println("taskEntity.getName() = " + taskEntity.getName());
System.out.println("taskEntity.getAssignee() = " + taskEntity.getAssignee());
System.out.println("taskEntity.getIdentityLinks() = " + taskEntity.getIdentityLinks());
System.out.println("taskEntity.getVariables() = " + taskEntity.getVariables());
}
}
全局配置类
@Configuration
public class Activiti7Config {
@Autowired
private SpringProcessEngineConfiguration config;
@PostConstruct
public void springProcessEngineConfiguration() {
// 设置自定义的全局事件监听器,其他配置方式就不需要配置了。
// config.setEventListeners(Collections.singletonList(new MyGlobalEventListener()));
// 开启日志监听,开启后对性能有影响 act_evt_log
config.setEnableDatabaseEventLogging(true);
}
}
测试流程
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestActivityGlobalEventListener {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
private static final String PROCESS_INSTANCE_ID = "728bb780-3be6-11ee-b0a5-18c04dcd4aee";
@Test
public void deployProcess() {
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("processes/global-listener.bpmn20.xml")
.deploy();
System.out.println("deploy = " + deploy);
}
@Test
public void startProcess() {
// 添加全局监听器
runtimeService.addEventListener(new MyGlobalEventListener(), ActivitiEventType.TASK_CREATED, ActivitiEventType.TASK_ASSIGNED, ActivitiEventType.TASK_COMPLETED);
Map<String, Object> variables = new HashMap<>();
variables.put("applyUserId", "user123456");
variables.put("candidateUsers", CollectionUtil.newArrayList("zhangsan", "lisi", "wangwu"));
variables.put("candidateGroups", CollectionUtil.newArrayList("group1", "group2", "group3"));
String processDefinitionKey = "global-listener";
String businessKey = processDefinitionKey + ":" + "100002";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
System.out.println("processInstance = " + processInstance);
// 输出当前任务列表
this.printTaskList(processInstance.getId());
}
@Test
public void completeTask() {
// 查询任务
Task task = taskService.createTaskQuery().processInstanceId(PROCESS_INSTANCE_ID).taskAssignee("user123456").singleResult();
taskService.complete(task.getId());
}
private void printTaskList(String processInstanceId) {
// 输出当前任务列表
taskService.createTaskQuery().processInstanceId(processInstanceId).orderByTaskCreateTime().asc().list().forEach(k -> {
System.out.println("===================任务列表===================");
System.out.println("任务ID = " + k.getId());
System.out.println("任务名称 = " + k.getName());
System.out.println("任务负责人 = " + k.getAssignee());
System.out.println("任务创建时间 = " + k.getCreateTime());
System.out.println("===================身份列表===================");
// 输出用户身份关系列表
taskService.getIdentityLinksForTask(k.getId()).forEach(link -> {
System.out.println("link.getType() = " + link.getType());
System.out.println("link.getUserId() = " + link.getUserId());
System.out.println("link.getGroupId() = " + link.getGroupId());
System.out.println("link.getTaskId() = " + link.getTaskId());
});
});
}
}
部署流程
运行 deployProcess
启动流程
运行 startProcess,可以看到监听到任务节点1的创建和分配事件。