JBPM3的任务分配方式主要由以下几种:
(1)直接设置actor-id属性,既可以设置固定的任务处理人,如actor-id='dinguangx'(这种情况在实际开发中极少用到的吧);也可以从流程变量中取出任务处理人,如actor-id="#{actorid}".
(2)通过TaskInstance实例直接调用API方法设置,如ti.setActor("dinguangx");;
(3)通过AssignmentHandler在任务创建的时候分配任务;这是最为常用的一种方式,也是最灵活的一种任务分配方式,可以在任务分配的时候做一些其他的操作;
(4)通过Swimlane的方式分配任务.通过第(3)种方式来分配任务时,虽然灵活,但是如果要将多个任务分配给同一个处理人时我们不得不编写多个handler类,造成java类的过度膨胀;这时候就可以通过Swimlane的方式来分配任务,多个相同处理人的Task结点只引用定义好的Swimlane就可以完成任务分配。
这里主要来分析一下使用Swimlane来实现任务分配的过程。
TaskInstance类中的assign(ExecutionContext)方法实现了任务的分配,下面的这段代码取自于TaskInstance类的源码.
public void assign(ExecutionContext executionContext) {
TaskMgmtInstance taskMgmtInstance = executionContext.getTaskMgmtInstance();
Swimlane swimlane = task.getSwimlane();
// if this task is in a swimlane
if (swimlane!=null) {
// if this is a task assignment for a start-state
if (isStartTaskInstance()) {
// initialize the swimlane
swimlaneInstance = new SwimlaneInstance(swimlane);
taskMgmtInstance.addSwimlaneInstance(swimlaneInstance);
// with the current authenticated actor
swimlaneInstance.setActorId(SecurityHelper.getAuthenticatedActorId());
} else {
// lazy initialize the swimlane...
// get the swimlane instance (if there is any)
swimlaneInstance = taskMgmtInstance.getInitializedSwimlaneInstance(executionContext, swimlane);
// copy the swimlaneInstance assignment into the taskInstance assignment
copySwimlaneInstanceAssignment(swimlaneInstance);
}
} else { // this task is not in a swimlane
taskMgmtInstance.performAssignment(task.getAssignmentDelegation(),
task.getActorIdExpression(),
task.getPooledActorsExpression(),
this,
executionContext);
}
updatePooledActorsReferences(swimlaneInstance);
}
我们假设当前任务不是位于Start-state中,并且使用Swimlane的任务分配方式,即task.getSwimlane()不为空,且isStartTaskInstance()为false的情况。
此时,代码将执行到
swimlaneInstance = taskMgmtInstance.getInitializedSwimlaneInstance(executionContext, swimlane);
再来看一下getInitializedSwimlaneInstance(ExecutionContext)方法执行的是什么工作:
public SwimlaneInstance getInitializedSwimlaneInstance(ExecutionContext executionContext, Swimlane swimlane) {
// initialize the swimlane
if (swimlaneInstances==null) swimlaneInstances = new HashMap();
SwimlaneInstance swimlaneInstance = (SwimlaneInstance) swimlaneInstances.get(swimlane.getName());
if (swimlaneInstance==null) {
swimlaneInstance = new SwimlaneInstance(swimlane);
addSwimlaneInstance(swimlaneInstance);
// assign the swimlaneInstance
performAssignment(swimlane.getAssignmentDelegation(),
swimlane.getActorIdExpression(),
swimlane.getPooledActorsExpression(),
swimlaneInstance,
executionContext);
}
return swimlaneInstance;
}
这个方法位于TaskMgmtInstance类中,而一个流程实例只对应一个TaskMgmtInstance实例,所以taskMgmtInstance实例中的swimlaneInstances将会包括流程实例中创建过的所有Swimlane实例。所以在getInitializedSwimlaneInstance方法执行时,如果任务是第一次被创建,将会根据设置的Swimlane创建一个新的SwimlaneInstance实例;否则就会在数据库中查询之前创建好的TaskInstance记录映射成TaskInstance对象返回给上一级调用过程。
再返回到assign()方法,紧跟着的处理代码是
copySwimlaneInstanceAssignment(swimlaneInstance);
下面是copySwimlaneInstanceAssignment方法的代码:
public void copySwimlaneInstanceAssignment(SwimlaneInstance swimlaneInstance) {
setSwimlaneInstance(swimlaneInstance);
setActorId(swimlaneInstance.getActorId());
setPooledActors(swimlaneInstance.getPooledActors());
}
很容易理解,就是将SwimlaneInstance中的actorId,pooledActors分配给当前任务。
注意到这里就存在一个问题,如果Task结点相应的任务不是第一次被创建,就不会再调用Swimlane的AssignmentHandler类来创建SwimlaneInstance。换句话说,Swimlane的AssignmentHandler类将只会被调用一次,而不是被多次调用,所以当流程用到Swimlane时(比如流程被审核退回再次提交审核时,审核结点就被多次执行到),AssignmentHandler类只执行一次,我们就不能在Swimlane中做额外的其他操作。比如,现在想把任务处理的URL设置在任务变量中,这个操作在AssignmentHandler类中进行;此时就会发现,当流程再次到达此结点时,任务变量中没有我们需要的值。原因也正在于此。
所以,更准确地说,普通的AssignmentHandler方式每次都选择任务处理人,而Swimlane一旦创建之后,就把处理人绑定,之后的任务实例不能再选择处理人了。
不过我们也可以利用它的这个特性实现一些其他的特殊业务.比如,一个共享的任务,如果被其中一个人选择处理,那么任务被退回之后再次到达此任务结点时,还应该由他来处理这个任务,就可以考虑通过设置SwimlaneInstance中的actorId来达到目的。
分享到:
相关推荐
JBPM3.2工作流开发指南 JBPM是一个扩展性很强的工作流系统,百分百用JAVA语言开发,持久层采用Hibernate实现,理论上说,只要Hibernate支持的数据库JBPM都支持。同时它还能被部署在任何一款JAVA应用服务器上。
jbpm3.2开发总结.pdf
jbpm3.2表说明 很详细 1.1 JBPM_PROCESSDEFINITION:流程模版表 关系表 外键存在表 外键名称 外键存在表字段 存在原因 可能 关系 JBPM_NODE JBPM_NODE FK_PROCST_SBPRCDEF SUBPROCESSDEFINITION_ 子流程的...
jbpm工作流开发指南,详细讲解了配置环境,步骤。
JBPM3.2与Spring结合时任务调度的实现.doc
用erstudio v7.1查看 博文链接:https://evanz.iteye.com/blog/106101
JBPM3.2 表初始化,流程发布,案例一
JBPM3.2 表初始化,流程发布第一课
jbpm3.2 .jar文件 发邮件 修该过后的jar,在这保留下,为以后有用,也希望对你有所帮助
jbpm3.2 mysql修改可用建表语句 在mysql命令行下使用:source D:1.sql
jbpm3.2 简单的请假流程 希望对大家有用!
jbpm3.2开发总结[定义].pdf
文档是自己通过学习JBPM3总结出来的,大家可以参考一下,包括插件的安装,开发流程,学习总结等等!
JBPM3.2,扫描版本,还算很清晰,虽然比较老,但是用来学习下还算不错,而且是中文,此文件因为太大,所以分为两个压缩包压缩,都已全部上传,请全部下载再解压缩。
开始跑jbpm提供的jbpm-console的时候老是报错,最后知道是缺少jar包的原因,这个rar中包含了jbpm3.2.x基本开发所需所有jar包。
JBPM3.2,扫描版本,还算很清晰,虽然比较老,但是用来学习下还算不错,而且是中文,此文件因为太大,所以分为两个压缩包压缩,都已全部上传,请全部下载再解压缩。
JBPM+STRUTS+SPRING整合
关于JBPM工作流引擎的最新说明文档。三个章节的
jbpm-jpdl-suite-3.2GA -(2)分开压缩(五个文件)jbpm下载 jbpm-jpdl-suite-3.2GA -(2)分开压缩(五个文件)jbpm下载
jbpm3.2所用的jar包,都是必备,不能少的,不用一个一个找。一次性全下载。直接导入就能用。