任务分派和组织建模是jBPM工作流引擎中两个重要的模块。作为一个设计出色,结构清晰的工作流引擎,jBPM在这两个模块的设计和实现上都有其值得学习的地方。
任务分派是所有工作流引擎都要支持的一个重要功能模块。其主要功能是管理任务的创建和分派。
任务(task)是流程定义的组成部分,它定义了在流程运行期间如何创建和分配任务实例。在jBPM中,任务是可以定义在任务节点(task-node)和流程定义(process-definition)中的。
任务实例(taskInstance)在被创建后会被分配给一个用户。jBPM中使用actorId (java.lang.String)作为用户的标识。所有创建好的任务实例都会存储在数据表JBPM_TASKINSTANCE中。用户可以在JBPM_TASKINSTANCE表中使用actorId进行查询,就能够得到相应人员的任务列表。
泳道(swimlane)是一个流程定义的元素。它用来支持在流程定义中将多个任务分配给同一个或者一组用户的功能。
在流程运行时,当第一次遇到任务实例分配给一个泳道的时候,引擎会创建相应的泳道实例(swimlaneInstance),并计算对应的用户,其后所有分配给这个泳道的任务实例都会分配给相同的用户。
jBPM的任务分派有两种模式,分别是推(push)模式和拉(pull)模式。
推模式是在任务分派的时候,直接将任务实例分派给一个指定的用户,任务实例进入这个用户的个人任务列表中。
拉模式是将任务实例分派给一组用户,这个任务实例会出现在组所有用户的组任务列表中。组用户需要首先将任务实例拉到自己的个人任务列表中才能够执行此任务。当有一个组用户取出了任务实例后,引擎就会将该任务实例从其他的组用户的组任务列表中去除。
PooledActor是pooledActors集合的元素的类型。
每个TaskInstance和SwimlaneInstance都可以分派给一个用户或者一组用户。如果分配一个用户,那么这个任务实例就直接进入了该用户的个人任务列表,如果分配给一组用户,那么这个任务实例就处于这一组用户的组任务列表中。
jBPM通过接口AssignmentHandler实现任务分派。
public interface AssignmentHandler extends Serializable {
void assign( Assignable assignable, ExecutionContext executionContext );
}
任务在定义的时候指定对应的AssignmentHandler接口实现类。引擎在创建任务实例的时候会调用接口中的assign方法。其实现应该调用参数assignable的方法对任务进行分派。
TaskInstance和SwimlaneInstance实现了接口Assignable。
public interface Assignable {
public void setActorId(String actorId);
public void setPooledActors(String[] pooledActors);
}
调用Assignable.setActorId(String actorId)方法可以将一个任务实例分派给一个用户,调用Assignable.setPooledActors(String[] actorIds)方法可以将一个任务实例分派给一组用户。
工作流引擎的组织建模问题一直都是一个难以统一解决的问题。不同应用背景,其组织模型会千差万别,因此jBPM采用了以非常简单的组织模型,并且能够非常容易的让使用者替换使用自己的组织模型。
jBPM为了能够将组织模型与引擎核心模块相分离,在引擎中只使用最基本的人员模型,而不使用任何其他的组织模型,其人员模型也只是使用一个String类型的actorId作为标识来进行任务分派。
jBPM提供了一个默认的组织模型,其对应的类为identity包和子包下面。使用的时候生成一个独立的identity的jar包,可以单独部署。
其中User代表一个用户或者能够提供某种服务的实体。Group代表一种可以有隶属管理的组织,比如组,公司,部门等。Membership表示user和group之间多对多的关系。所有的这些都从Entity类继承而来。
如果用户使用jBPM自带的默认组织模型,那么在使用jPDL(jBPM自己的工作流建模语言)定义流程的时候,还可以使用任务分派的扩展定义。
如果用户需要在应用中使用自己的组织模型,那么在部署jBPM的时候,只要从它的hibernate.cfg.xml文件中去掉User,Group,Membership三个类对应的配置项,这样就可以在部署的时候不需要jBPM.identity包了。
在每个任务分派类(实现了AssignmentHandler接口的类)的 void assign( Assignable assignable, ExecutionContext executionContext )方法中,只需要根据用户自己组织模型计算得到最终的任务执行人,然后以任务执行人的Id作为参数调用assignable.setAcotrId(String)或者assignable.setPoolActors(String[]),就可以将任务实例分派给指定的人员了。
<转:http://blog.csdn.net/dust_bug/archive/2007/04/11/1559844.aspx>