jbpm任务分配分析

jbpm任务分配分析
任务节点的任务资源分配(负责人分配,能执行一个任务的人或者系统通称资源):
相关对象:
1. Swimlane:流程中的脚色定义.这里参照了活动图的概念
2. SwimlaneInstance:流程中角色定义实例.
3. TaskmgmtInstance:任务管理的运行时模块。它协助了ProcessInstance保管一个流程运行时的任务信息,并有一些关于任务分配管理的操作。
4. TaskNode:任务载体
5. Task:代表任务定义。静态的过程定义中的一部分
6. TaskInstance:此对象表示表示任务实例。Token进入TaskNode后会马上循坏Task中的 条件Condition(一个jbpm的脚本),一旦瞒住马上生成TaskInstance。

Jbpm的任务分配有2种模式:推模式和拉模式。其中taskInstance中的actorId :String实现了推,而pooledActors实现了拉。PooledActors中包含了数个PoolActor对象。此对象包装了一个actorid和多个taskinstance,swimlaneInstance


当token处于任务节点,会循环任务节点的task集合.生成taskInstance对象.生成对象的最后一步,就是分配资源(负责人)给各个taskInstance.原理如下:

1. 检查task是否被分配了一个swimlane对象.如果有跳到2.没有跳到5
2. 判断此任务是否位于startState,即是否是起始任务.起始任务用来启动整个流程的开始.该任务用来代替手动调用processInstance.signal();如果是起始任务将会启动身份鉴定组件来设置actorid;此任务负责人也是整个流程的发起者。
3. 如果不是起始任务.将会使用getInitializedSwimlaneInstance()方法,根据运行环境和swimlane生成一个swimlaneInstance;这是一个关于swimlaneInstance的工厂方法。
此方法大概分2步:1.以swimlane的name为key检查TaskmgmtInstance中的swimlaneInstances域是否已经包含了swimlaneInstance域,有的话直接返回。2.如果不存在角色实例,就根据swimlane生成一个角色实例.之后将调用performAssignment方法决定负责人,途径有2个: 1.外部实现assignHandler接口.并包装成一个delegation对象关联到swimlane上,2.解析actionidexpression,得到actorid注入taskinstance。解析poolactoridexpression得到poolactors并注入taskinstance。2个途径优先级关系为1〉2。
4. 经过3得到的swimlaneInstance中已经包含了负责人信息,把负责人信息用taskinstance 的方法copySwimlaneInstanceAssignment拷贝进taskinstance即完成了任务分配。
5. 如果一个task没有分配一个swimlane.那么将根据task中的资源分配信息进行分配:task和swimlane一样.都具有delegation,actoridexpression,以及poolActorIdExpression3个资源分配信息域。而taskInstance与swimlaneInstance实现了同样的资源分配接口。所以这种情况下将和3步骤中一样调用TaskmgmtInstance中的performAssignment方法。直接为taskInstance分配资源。
6.最终的设置结束之后,由于taskintance中的poolactor是3个对象的包装类,所以还要为每一个poolactor对象设置反向关联关系。关联到此taskInstance和taskInstance中的swimlaneInstance

任务分配总结:总的看来jbpm的任务分配,优先使用角色的资源分配方式。如果该任务没有关联到任何角色,才使用task上自身的资源分配方式。引入角色概念。可以在一个流程中重复使用一个角色信息。

任务实例和图执行
任务实例是参与者任务清单(tasklist)中的项目,任务实例可以作为信号,当一个信号任务实例完成时,可以发送一个信号到它的令牌继续流程执行。任务实例可以被阻塞,这意味着在任务实例完成之前相关令牌(=执行路径)不允许离开任务节点。默认情况下,任务实例是信号非阻塞的。
如果多于一个任务实例与一个任务节点关联,流程开发者可以指定任务实例的完成怎样影响流程的继续。下面是可以给任务节点的signal属性设置的值:
l last:这是默认值。当最后一个任务实例完成时继续执行;当在节点入口处没有任务创建时,继续执行。
l last-wait:当最后一个任务实例完成时继续执行;当在节点入口处没有任务创建时,执行在任务节点等待,直到任务被创建。
l first:当第一个任务实例完成时继续执行;当在节点入口处没有任务创建时,继续执行。
l first-wait:当第一个任务实例完成时继续执行;当在节点入口处没有任务创建时,执行在任务节点等待,直到任务被创建。
l unsynchronized:总是继续执行,不管任务是否创建和完成。
l never:执行不再继续,不管任务是否创建和完成。
任务实例可以基于运行时的计算创建,如果那样的话,需要添加一个ActionHandler到任务节点的node-enter事件,并且设置属性create-tasks=“false”。下面是这样一个动作的实现例子:
public class CreateTasks implements ActionHandler {
public void execute(ExecutionContext executionContext) throws Exception {
Token token = executionContext.getToken();
TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();

TaskNode taskNode = (TaskNode) executionContext.getNode();
Task changeNappy = taskNode.getTask("change nappy");

// 现在, 相同任务的两个任务实例被创建
tmi.createTaskInstance(changeNappy, token);
tmi.createTaskInstance(changeNappy, token);
}
}
如示例所展示,任务可以在指定的任务节点中创建,它们也可以被指定到process-definition,并且从TaskMgmtDefinition获取。TaskMgmtDefinition用任务管理信息扩展了ProcessDefinition。
标识任务示例完成的API是TaskInstance.end(),你可以在end方法中指定一个转换,如果这个任务的完成会触发继续执行,则会通过指定的转换离开任务节点。
11.3 分配
流程定义包含任务节点,任务节点(task-node)包含一个或多个任务,任务作为流程定义的一部分是静态描述。在运行时,任务导致任务实例的创建,一个任务实例对应某人任务列表中的一个入口。
在Jbpm中,可以结合使用推模式和拉模式(见下文)的任务分配。流程可以计算任务的责任人,并把它推到他/她的任务清单里;或者,任务可以被分配到参与者池,这种情况下,池中的每个参与者都可以拉出任务并把它放入参与者的个人任务清单。
11.3.1 分配接口
通过接口AssignmentHandler进行任务实例分配:
public interface AssignmentHandler extends Serializable {
void assign( Assignable assignable, ExecutionContext executionContext );
}
当任务实例被创建时分配处理的实现被调用,在那时,任务实例可以被分配到一个或多个参与者。AssignmentHandler实现将调用分配方法(setActorId或setPooledActors)分配任务,可以分配一个任务实例或者一个泳道实例swimlaneInstance(=流程角色)。
public interface Assignable {
public void setActorId(String actorId);
public void setPooledActors(String[] pooledActors);
}
任务实例和泳道实例都可以被分配到一个用户或者共享参与者。分配任务实例到一个用户,调用Assignable.setActorId(String actorId);分配任务实例到候选的共享参与者,调用Assignable.setPooledActors(String[] actorIds)。
流程定义中的每个任务都可以与一个分配处理实现相关联,用来完成运行时的任务分配。
当流程中的多个任务将要分配给相同的人或者参与者组时,考虑使用泳道。
考虑到AssignmentHandler的重用,每个AssignmentHandler的使用可以在processdefinition.xml中配置。请参考“16.2 委托”了解怎样添加分配处理配置的更多信息。

你可能感兴趣的:(jbpm,配置管理,项目管理,活动,脚本)