flowable 监听器
目录
- 前言
- 一、监听器
- 二、创建bpmn.xml
- 三、测试
前言
本文主要用于测试在创建流程实例时,通过监听器动态修改任务的审批人。
一、监听器
实现 org.flowable.engine.delegate.TaskListener 接口,创建监听器
public class CreateProcessInstanceEvent implements TaskListener {@Overridepublic void notify(DelegateTask delegateTask) {String name = delegateTask.getName();System.out.println(name);if (name.equals("admin审批")){delegateTask.setAssignee("admin10");}}
}
二、创建bpmn.xml
通过 flowable-ui 的创建流程的界面设置监听器
然后保存并下载 bpmn 文件,在 userTask 里多了监听器的信息
<userTask id="sid-B6DF703A-E401-42A2-908C-D9F81E47FEC9" name="admin审批" flowable:assignee="admin" flowable:formFieldValidation="true"><extensionElements><flowable:taskListener event="create" class="com.iscas.biz.flowable.CreateProcessInstanceEvent"></flowable:taskListener><modeler:activiti-idm-assignee xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee><modeler:assignee-info-email xmlns:modeler="http://flowable.org/modeler"><![CDATA[test-admin@example-domain.tld]]></modeler:assignee-info-email><modeler:assignee-info-firstname xmlns:modeler="http://flowable.org/modeler"><![CDATA[admin]]></modeler:assignee-info-firstname><modeler:assignee-info-lastname xmlns:modeler="http://flowable.org/modeler"><![CDATA[admin]]></modeler:assignee-info-lastname><modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements></userTask>
三、测试
1、部署流程
@Testpublic void createDeployment() {Deployment deployment = repositoryService.createDeployment().addClasspathResource("process-test.bpmn20.xml").deploy();System.out.println(deployment.getId());}
2、启动流程
根据流程定义的 key process-test 启动流程
@Testpublic void startProcessDefinition() {Map<String, Object> variables = new HashMap<String, Object>();variables.put("employee", "张三");variables.put("nrOfHolidays", 3);variables.put("description", "有事请假");ProcessInstance processInstance =runtimeService.startProcessInstanceByKey("process-test", variables);}
在创建程过程中,会回调监听器,下面分析一下 userTask 的流程
(1)executeOperations()
CommandInvoker 使用 while 循环继续调用新的 ExecutionEntity ,下面从调用 userTask 的 ContinueProcessOperation 开始
protected void executeOperations(final CommandContext commandContext) {FlowableEngineAgenda agenda = CommandContextUtil.getAgenda(commandContext);while (!agenda.isEmpty()) {Runnable runnable = agenda.getNextOperation();executeOperation(commandContext, runnable);}}
(2)ContinueProcessOperation.run()
@Overridepublic void run() {// UserTask FlowElement currentFlowElement = getCurrentFlowElement(execution);if (currentFlowElement instanceof FlowNode) {continueThroughFlowNode((FlowNode) currentFlowElement);} else if (currentFlowElement instanceof SequenceFlow) {continueThroughSequenceFlow((SequenceFlow) currentFlowElement);} else {throw new FlowableException("Programmatic error: no current flow element found or invalid type: " + currentFlowElement + ". Halting.");}}
(3)continueThroughFlowNode
protected void continueThroughFlowNode(FlowNode flowNode) {...executeSynchronous(flowNode);...}
(4)executeSynchronous()
protected void executeSynchronous(FlowNode flowNode) {...// Execute actual behavior//封装了用户任务和监听器等ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior();if (activityBehavior != null) {//执行 activityBehavior executeActivityBehavior(activityBehavior, flowNode);executeBoundaryEvents(boundaryEvents, boundaryEventExecutions);} else {executeBoundaryEvents(boundaryEvents, boundaryEventExecutions);LOGGER.debug("No activityBehavior on activity '{}' with execution {}", flowNode.getId(), execution.getId());CommandContextUtil.getAgenda().planTakeOutgoingSequenceFlowsOperation(execution, true);}}
(5)executeActivityBehavior()
protected void executeActivityBehavior(ActivityBehavior activityBehavior, FlowNode flowNode) {...activityBehavior.execute(execution);... }
@Overridepublic void execute(DelegateExecution execution) {execute(execution, null);}
@Overridepublic void execute(DelegateExecution execution, MigrationContext migrationContext) {CommandContext commandContext = CommandContextUtil.getCommandContext();ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService();//创建taskTaskEntity task = taskService.createTask();//设置属性task.setExecutionId(execution.getId());task.setTaskDefinitionKey(userTask.getId());task.setPropagatedStageInstanceId(execution.getPropagatedStageInstanceId());...//保存任务、历史任务、任务用户关联信息TaskHelper.insertTask(task, (ExecutionEntity) execution, !skipUserTask, (!skipUserTask && processEngineConfiguration.isEnableEntityLinks()));}...//回调监听器processEngineConfiguration.getListenerNotificationHelper().executeTaskListeners(task, TaskListener.EVENTNAME_CREATE);
(6)executeTaskListeners()
public void executeTaskListeners(TaskEntity taskEntity, String eventType) {if (taskEntity.getProcessDefinitionId() != null) {org.flowable.bpmn.model.Process process = ProcessDefinitionUtil.getProcess(taskEntity.getProcessDefinitionId());FlowElement flowElement = process.getFlowElement(taskEntity.getTaskDefinitionKey(), true);if (flowElement instanceof UserTask) {UserTask userTask = (UserTask) flowElement;//执行任务的监听器executeTaskListeners(userTask, taskEntity, eventType);}}}
(7)executeTaskListeners()
public void executeTaskListeners(UserTask userTask, TaskEntity taskEntity, String eventType) {for (FlowableListener listener : userTask.getTaskListeners()) {//校验事件类型String event = listener.getEvent();if (event.equals(eventType) || event.equals(TaskListener.EVENTNAME_ALL_EVENTS)) {BaseTaskListener taskListener = createTaskListener(listener);if (listener.getOnTransaction() != null) {ExecutionEntity executionEntity = CommandContextUtil.getExecutionEntityManager().findById(taskEntity.getExecutionId());planTransactionDependentTaskListener(executionEntity, (TransactionDependentTaskListener) taskListener, listener);} else {taskEntity.setEventName(eventType);taskEntity.setEventHandlerId(listener.getId());try {//将任务封装到 TaskListenerInvocationCommandContextUtil.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new TaskListenerInvocation((TaskListener) taskListener, taskEntity));} finally {taskEntity.setEventName(null);}}}}}
(8)handleInvocation()
public void handleInvocation(DelegateInvocation invocation) {invocation.proceed();}
public void proceed() {invoke();}
protected void invoke() {executionListenerInstance.notify(delegateTask);}
public void notify(DelegateTask delegateTask) {//反射创建监听器对象 useClassForName ? Class.forName(className, true, classLoader) : classLoader.loadClass(className);TaskListener taskListenerInstance = getTaskListenerInstance();//调用监听器 CommandContextUtil.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new TaskListenerInvocation(taskListenerInstance, delegateTask));}
然后检查数据库的 ACT_RU_TASK 表 ,新增的任务的 assignee_ 字段被监听器修设置成了 admin10
flowable 监听器相关推荐
- Flowable 流程引擎系列文章导读
Flowable 流程引擎系列文章导读 集成篇 入门教程篇 功能篇 其他问题 集成篇 Flowable 快速入门教程:SpringBoot 集成 Flowable + Flowable Modeler ...
- flowable集成spring boot ----任务监听器
任务监听器 任务监听器(task listener)用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式. 任务监听器包含下列属性: event(事件)(必填):触发任务监听器的任务事件类 ...
- Flowable全局监听器-待办消息提醒
项目需要在每个待办Task到达时,发送一个消息提醒用户过来处理.不想在每个工作流单独加监听器,这时候可以使用Flowable的全局监听器. 定义一个监听器 package com.azhuzhu.fl ...
- 工作流引擎 SpringBoot+flowable完美结合,快速实现工作流,so easy
flowable 起源 在2016.7~2017.5期间activiti团队内部已经产生了重大的分歧.关于新的activiti新团队与原有的团队重要开发人员我们罗列一下,细节如下: 上图是Tijs R ...
- Flowable学习笔记(二、BPMN 2.0-基础 )
转载自 Flowable学习笔记(二.BPMN 2.0-基础 ) 1.BPMN简介 业务流程模型和标记法(BPMN, Business Process Model and Notation)是一套图 ...
- 工作流实战_23_flowable 任务监听器 事件监听器
项目地址:https://gitee.com/lwj/flowable.git 分支flowable-base 视频讲解地址 https://www.bilibili.com/video/av7932 ...
- flowable用户组的处理
背景 flowable有自己的用户账号信息,用户信息,用户组信息,其实这些用户信息都我们系统可能都存在,那么我们如何去使用一份数据呢? 1.我们可以建立视图直接取我们的组织信息,这个可以参考相关的文档 ...
- Flowable工作流入门
Flowable工作流入门 本文链接:https://blog.csdn.net/qq_37059838/article/details/83576097 原作者:吕小小布 下载地址:Flowable ...
- Flowable工作流引擎技术方案
应对越来越多的工作流使用场景,以及越来越灵活的业务情形,我们亟需对工作流引擎进行一次重构优化.目前市场上主流的工作流引擎,一种是我们熟知的activiti,另外一种就是flowable.众所周知,fl ...
最新文章
- android实现iphone风格的picker
- ActivityRouter
- Mybatis Plus——[Could not set property 'id' of '***' with value]解决方案
- [GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(中)
- linux查看编译器的大小端,Linux系统大小端判断
- 二级c语言考试改卷标准,计算机二级C语言笔试试卷
- [转载] python histogram函数_Python numpy.histogram_bin_edges函数方法的使用
- 设计模式:卑微的代理模式
- 在民间借贷软件开发中用到的电子文档存储技术
- fusioncharts java_FusionCharts在Java中的基本使用(2)
- 执行shellcode一直提示illegal instruction
- 加密流量分类-论文2:Deep Packet: A Novel Approach For Encrypted Traffic Classification Using Deep Learning
- 现在各种云建站,挑两个给大家分析一下。
- 未明学院:量化金融训练营开始报名,成为兼具数据分析技能+项目实战经验的复合型人才!
- 医学统计学 第五章(定性资料的统计描述)
- 登录模块与token的使用和创建
- 苹果cms10好看的模板
- OmniPlan Pro 3 for Mac v3.12.3 项目规划软件 中文破解版下载
- 关于linux的音频驱动
- 上传图片预览(服务器版)组件