1、固定分配
在绘制流程图或者直接在流程文件中通过Assignee来指定的方式。直接是写死的。
2、表达式分配
Flowable使用UEL进行表达式解析。UEL代表Unified Expression Language,是EE6规范的一部分(查看EE6规范了解更多信息)。
表达式可以用于Java服务任务(Java Service task)、执行监听器(Execution Listener)、任务监听器(Task Listener) 与 条件顺序流(Conditional sequence flow)等。尽管有值表达式与方法表达式这两种不同的表达式,Flowable通过抽象,使它们都可以在需要表达式
的地方使用。
- 值表达式 Value expression: 解析为一个值。默认情况下,所有流程变量都可以使用。(若使用Spring)所有的Spring bean也可以用在表达式里。例如:
${myVar}
${myBean.myProperty}
myBean是Spring容器中的个Bean对象,表示调用的是bean的addNewOrder方法
首先新建一个值表达式的例子
可视编辑器–>分配用户–>固定值—>${assignee1}
在次流程部署了之后,在流程定义信息表中可以看到此流程的相关信息
/**
* 启动流程实例
*/
@Test
public void TestDeploymentRun() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 流程变量
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("assignee0", "张三");
variables.put("assignee1", "李四");
// 启动流程实例
// ProcessInstance processInstance = runtimeService.startProcessInstanceById("holidayRequest:1:37504", variables);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("MyHolidayUI001", variables);
System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // MyHolidayUI001:1:37504
System.out.println("processInstance.getProcessDefinitionKey() = " + processInstance.getProcessDefinitionKey());// MyHolidayUI001
System.out.println("processInstance.getActivityId() = " + processInstance.getActivityId());
System.out.println("processInstance.getId()" + processInstance.getId());// 40001
}
可以看到我们设置的变量
在task表中,可以看到当前分配人是张三,说明值表达式被解析了
/**
* 完成任务
*/
@Test
public void TestCompleteTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processInstanceId("40001") //根据流程实例编号查找
.taskAssignee("张三")
.singleResult();
taskService.complete(task.getId());
}
在张三完成任务之后,task表中的分配人变成了李四
- 方法表达式 Method expression: 调用一个方法,可以带或不带参数。**当调用不带参数的方法时,要确保在方法名后添加空括号(以避免与值表达式混淆)。**传递的参数可以是字面值(literal value),也可以是表达式,它们会被自动解析。例如:
${printer.print()}
${myBean.addNewOrder('orderName')}
${myBean.doSomething(myVar, execution)}
请注意,表达式支持解析(及比较)原始类型(primitive)、bean、list、array与map。
3、监听器分配
我们在此处使用监听器来完成负责人的指定,那么我们在流程设计的时候就不需要指定assignee。但是需要指定任务监听器。
创建自定义监听器:
public class MyTaskListener implements TaskListener {
public void notify(DelegateTask delegateTask) {
System.out.println("监听器被触发了:" + delegateTask.getName() + "==" + delegateTask.getEventName());
if("提交请假流程".equals(delegateTask.getName()) &&
"create".equals(delegateTask.getEventName())){
// 指定任务的负责人
delegateTask.setAssignee("小明");
} else {
delegateTask.setAssignee("小张");
}
}
}
之后,在流程设计的时候,指定任务监听器。这里两个节点指定同一个监听器,意味着会触发两次,当然,你也可以为他们指定不同的监听器。
部署流程之后,
/**
* 启动流程实例
*/
@Test
public void TestDeploymentRun() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 启动流程实例
// ProcessInstance processInstance = runtimeService.startProcessInstanceById("holidayRequest:1:37504", variables);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("MyHolidayUI001NoAssignee");
System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId());
System.out.println("processInstance.getProcessDefinitionKey() = " + processInstance.getProcessDefinitionKey());
System.out.println("processInstance.getActivityId() = " + processInstance.getActivityId());
System.out.println("processInstance.getId()" + processInstance.getId());
}
启动流程,在日志中打印了如下信息,说明监听器被触发了,分配人呗设置成了小明。
监听器被触发了:提交请假流程==create
/**
* 完成任务
*/
@Test
public void TestCompleteTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processInstanceId("52501") //根据流程实例编号查找
.taskAssignee("小明")
.singleResult();
taskService.complete(task.getId());
}
小明去完成任务,在日志中打印了如下信息,说明监听器被触发了,分配人呗设置成了小张。
监听器被触发了:总经理审批==create