jBPM开发:任务管理
三月 2, 2009 in Java开源
1,任务
任务可以在process-definition中用 task-node 定义,最常用的方式是用一个task-node定义一个或多个任务。这种情况下 task-node 代表一个由用户完成的任务,并且流程执行将一直等待参与者完成这个任务,当参与者完成任务,流程执行将继续。当多个任务在 task-node被指定,默认的行为是等待所有的任务被完成,也可以更改task-node的选项来改变它的行为。
2,任务实例
任务实例可以被分配给一个actorId (java.lang.String),所有的任务实例被保存在数据库表中(JBPM_TASKINSTANCE),可以通过actorId查询这个表来得到所有的任务实例,将会得到特定用户的任务清单。
在多个任务同一个task-node关联的情况下,开发者可以指定怎样完成任务实例来影响流程的继续,下面是一个给task-node的singal-property的可选列表
last : 这是默认的,当最后一个任务完成时发出signal信号;当task-node没有建立任何任务时,直接发出signal信号
last-wait : 当最后一个任务完成时发出signal信号;当task-node没有建立任何任务时等待
first : 当第一个任务完成时发出signal信号;当task-node没有建立任何任务时,直接发出signal信号
first-wait : 当第一个任务完成时发出signal信号;当task-node没有建立任何任务时等待
unsynchronized :直接发出signal信号
never :停留在task-node,不发出signal信号
如果必须基于运行时的信息来决定任务实例的创建,那必须在task-node的node-enter事件中添加一个ActionHandler,并且设置task-node的create-tasks=”false”,这样意味着流程执行到任务节点的时候,会执行node-enter中的ActionHandler程序代码,在程序代码中来动态创建任务实例。
下面是一个ActionHandler实现的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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"); // now, 2 task instances are created for the same task. tmi.createTaskInstance(changeNappy, token); tmi.createTaskInstance(changeNappy, token); } } |
3,任务分配
流程定义包含任务节点,task-node包含0到多个任务,任务是流程定义的静态描述,在运行期间,任务导致任务实例的建立,一个任务实例对应着个人任务列表里的一个入口。
在jBPM,推 和 拉 模式的任务分派可以组合使用,流程能计算任务的职责并把它”推”到他/她的任务清单里(tasklist),或者另外把任务分配给参与者池,这种情况下池中的每一个参与者可以”拉”任务并且把它们放到参与者个人的任务清单里(tasklist)。
通过接口AssignmentHandler来分配任务实例:
1 2 3 | public interface AssignmentHandler extends Serializable { void assign( Assignable assignable, ExecutionContext executionContext ); } |
一个分配handler的实现在任务实例创建的时候被调用,在这个时候,任务实例可以分配给一个或多个参与者。AssignmentHandler的实现可以调用 Assignable 方法(setActorId或 setPooledActors )来分配任务,可分配的要么是一个 TaskInstance 或者 SwimlaneInstance (= 流程角色)。
1 2 3 4 | public interface Assignable { public void setActorId(String actorId); public void setPooledActors(String[] pooledActors); } |
TaskInstances 和 SwimlaneInstances 两者都可以分配给指定的用户或参与者池,分配一个TaskInstance给用户,调用 Assignable.setActorId(String actorId) ;分配一个TaskInstance给候选参与者池,调用 Assignable.setPooledActors(String[] actorIds)。
4,任务事件
任务有动作关联,有4个标准任务事件类型定义: task-create、task-assign、task-start 和 task-end。
task-create 在任务实例建立的时候被触发
task-assign 当任务实例被分配的时候被触发。当动作被这个事件执行的时候,可以通过 executionContext.getTaskInstance().getPreviousActorId()访问前一个参与者
task-start 是当 TaskInstance.start()被调用时触发,它被用来标示用户真正开始了这个任务实例
task-end 当 TaskInstance.end(…)被调用时触发,这标记着任务的完成,如果任务和流程执行相关联,这个调用将触发流程的继续执行
因此任务可以有事件和动作, 异常handlers也可以在指定给任务
5,身份组件模型
用户管理、组和权限管理一般都称做身份管理,jBPM包括可选的身份组件,它可以很容易的使用公司自己的身份数据存储来替换
jBPM 身份管理组件包括组织层次模型,任务的分配根据组织层次来完成,因此这个隐含的组织层次模型描述了用户、组、系统和它们之间的关系。作为可选的部分,权限和角色也可以包含在组织模型中。下图是身份组件模型:
身份组件模型是用在任务分配表达式动态分配任务的时候,如下:
1 2 3 4 5 6 7 8 | ...
group(hierarchy) --> member(boss)" />
... |
分配语法表达式如下:
1 2 3 4 5 6 7 8 9 10 11 | first-term --> next-term --> next-term --> ... --> next-term
where
first-term ::= previous |
swimlane(swimlane-name) |
variable(variable-name) |
user(user-name) |
group(group-name)
and
next-term ::= group(group-type) |
member(role-name) |
第一术语first-term
表达式分析是从左向右解析的,first-term指明了在身份模型中的用户或组,以后的术语从中间的用户或组来计算下一个术语。
previous 意思是任务被分派给当前已经验证过的参与者,这意味着参与者在流程中执行前一个步骤。
swimlane(swimlane-name) 用户或组从指明的泳道实例取得
variable(variable-name) 用户或组从指明的变量实例取出,变量实例包含 java.lang.String,用户或组从身份组件中获得
user(user-name) 用户从身份组件里根据用户名取得
group(group-name)从身份组件里根据组名取得
下一个术语 Next terms
组(group-type) 得到用户的组,前一个术语(previous terms)得到用户,它根据给定的group-type搜索组下的所有用户成员
member(role-name) 从组里得到给定角色下的用户,前一个术语(previous terms) 必须是一个组,搜索给定角色下的所有用户成员
如果希望使用自己的组织层次模型或者自己的身份验证数据,可以不使用jBPM提供的身份组件模型,只要从配置文件hibernate.cfg.xml中删除以下几行:
1 |
ExpressionAssignmentHandler是基于jBPM的身份组件模型,因此不能够再使用它,如果想继续使用它的话,需要ExpressionAssignmentHandler和自己的数据进行绑定,需要继承ExpressionAssignmentHandler并覆盖实现getExpressionSession方法:
1 | protected ExpressionSession getExpressionSession(AssignmentContext assignmentContext); |
任务管理重还涉及到 泳道(swinlane)和任务定时器,但是由于我在这次的项目开发中并未使用到它,因此本文中将其省略。
–
相关文章:
sulin said on 九月 13, 2009
老大,“只要从配置文件hibernate.cfg.xml中删除以下几行”后面的XML怎么是空的?