本文主要用于测试在创建流程实例时,通过监听器动态修改任务的审批人。
实现 org.flowable.engine.delegate.TaskListener 接口,创建监听器
public class CreateProcessInstanceEvent implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
String name = delegateTask.getName();
System.out.println(name);
if (name.equals("admin审批")){
delegateTask.setAssignee("admin10");
}
}
}
通过 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、部署流程
@Test
public void createDeployment() {
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("process-test.bpmn20.xml")
.deploy();
System.out.println(deployment.getId());
}
2、启动流程
根据流程定义的 key process-test 启动流程
@Test
public 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()
@Override
public 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);
...
}
@Override
public void execute(DelegateExecution execution) {
execute(execution, null);
}
@Override
public void execute(DelegateExecution execution, MigrationContext migrationContext) {
CommandContext commandContext = CommandContextUtil.getCommandContext();
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService();
//创建task
TaskEntity 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 {
//将任务封装到 TaskListenerInvocation
CommandContextUtil.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