浏览 2835 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-23
最后修改:2010-03-23
(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来达到目的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-09-13
不错,收益
|
|
返回顶楼 | |