进阶篇
一、该版本中使用了Pooled Actor机制,而不是actor-id。
**解释:就是说通过Pooled Actor可以将一个任务一次分配给一组(多个)参与者,
注意这和之前不一样,之前是针对同一个任务,然后产生多个任务实例对象,
然后每个实例对象对应一个任务的参与者,其实还是相当于一个任务对应了一个参与者;
现在说的使用Pooled Actor是将一个任务的一个任务实例对象分配给一组参与者。
**运行原理:
当把一个任务的一个任务实例对象分配给一组参与者之后,
那么该组参与者的每个成员登陆系统后,都可以看到该任务列表
(此时调用显示用户代办列表的方法较之前有区别,是带有pooled字符串的方法),
但是当其中的一个参与者开启了任务(调用了start()方法,不论之后是否也调用了end()处理任务的方法),
那么此时该组的其他参与者就不能再看到该任务了,因为任务已经得到了处理;
换句话说就是任务只有一个,而处理任务的参与者却有多个,
但是最终任务的处理只能被一个参与者处理,任务处理完之后就可以进入下一个节点了。
****具体解释:
其实当JBPM流转到包含有分配一组参与者的任务<task>的节点<task-node>的时候,
和之前一样,仍然会自动创建任务实例对象,此处因为使用的是PooledActor为任务分配的参与者,
所以JBPM对任务实例对象做了特殊处理,我们会在数据库表中看到,虽然创建了任务实例,
但是对象的表记录中的actorId是null,根本就没有值,这里的原因就是因为是一个任务分给了一组,
但是最后必须有一个参与者处理,该actorId字段的值,是在该任务实例对象调用start()开始方法的时候,
通过代码指定一个要处理该任务的参与者编号(当然这个参与者必须属于组之中的一个),
这样该任务就只对调用start()方法时指定了参与者的这个参与者可见,不管该参与者是不是进行处理该任务,
即是否调用end()方法,只要它在启动任务,即调用start()方法时指定了自己作为任务的处理者,
那么对于组中的其他参与者就对该任务都不可见了。
**具体实现:三个大步骤!!!
1.在流程定义文件中为任务指定一个类
<task-node name="taskNodeName">
<task name="taskName">
<assignment class="com.lj.handler.PooledAssignmentHandler"/>
</task>
<transition name="transitionName" to="flowToName"></transition>
</task-node>
2.分配参与者的类的具体实现:
public class PooledAssignmentHandler implements AssignmentHandler{
public void assign(Assignable assignable, ExecutionContext executionContext) throws Exception{
//一组参与者的编号ID
String[] actors = {"1","2","3"};
//为任务分配一组参与者
assignable.setPooledActors(actors);
}
}
3.获取登陆人员代办任务列表的时候和之前有点区别:
//根据当前登陆的用户ID获得任务列表
//估计这样只能获取通过setPooledActors()方法分配的任务,之前那种估计还得用之前的方式,自己试验后确实是这样
//所以下边获得的都是通过setPooledActors()这种方法分配的参与者的任务列表
List list = jbpmContext.getTaskMgmtSession().findPooledTaskInstances(userId);
//循环各任务
for(int i = 0; i < list.size(); i++){
//得到一个任务
TaskInstance taskInstance = (TaskInstance)list.get(i);
/*启动任务,因为上面说过创建任务的时候actor-id字段是没有参与者的值的,
所以启动流程的时候要把启动流程的参与者(即自己)设置为处理该任务的参与者,
也就是说这样的话actor-id字段中的值就是userId了,
那么此时不论userId参与者是否调用end()方法来处理该任务,
那么改组的其他参与者都将不能再看到该任务了*/
taskInstance.start(userId);
}
**提示:获得任务列表后对于这种使用PooledActor的方式的处理,
一般不立即就start()任务,因为如果立即启动的话那么意味着谁先登陆谁先看到这个任务那么这个任务就由谁办理;
所以一般都是先显示,当点击"办理"等一个动作后,然后再调用start()方法,并且传入当前参与者的ID,
表示当前用户要对任务进行处理。