jBPM开发:实现审批工作流(二)
三月 13, 2009 in Java开源
本文紧接前面,描述实现审批流程的流程定义
一,流程定义图
二,各节点描述
- start:流程的起点,只要启动流程就会从它开始自动往下执行,每个流程必须有一个开始节点
- 查找审批人:它是一个节点类型,用来根据启动流程时的人来从demo_employee_hierarchies表中查找上级主管,根据查找的结果得出:找到审批人和到不到审批人,这个节点执行了Java代码后会自动转到下一个节点,不等待
- 审批单据:它是一个任务节点类型,用来根据查找审批人的结果,为审批人创建一个代办事项任务,其中包括2个方面:一是为审批人创建一个任务实例;而是为审批人创建一个代办事项。这个节点会等待审批人做出动作后再往下执行,否则一直处于等待中
- 检查权限:它是一个节点类型,用来检查审批人的职位上面所具备的审批金额,如果它超过了提交审批的金额,则检查通过,否则不通过,它从demo_control_rules表中取得相关信息。这个节点不会等待
- 批准、不批准和无审批人:它们是流程的结束点,每一个流程必须至少有一个结束点,执行到这些点的任意一个点都意味着流程的结束。
三,流程定义文件
1 |
上面需要注意的几个选项:
action class:代表执行到此节点或者此节点的某个时刻时所执行的Java代码
create-tasks=”false”:代表了任务节点不会自动创建任务实例,而是留给action class来完成
signal=”first”:代表如果在这个任务节点下创建了多个任务实例,只要其中任何一个任务实例执行介绍,任务节点结束然后转到下一个节点。
四,“查找审批人”节点处理
节点对应的动作处理类为:com.hand.bpm.approve.demo.FindApprover,它需要实现接口org.jbpm.graph.def.ActionHandler方法:
1 | void execute( ExecutionContext executionContext ) throws Exception; |
FindApprover代码逻辑:
- 从jBPM的环境中取得变量fromUserName的值,它表示审批的请求从谁哪里提交上来,它决定了会提交给谁进行审批
- 使用HSQL从DemoUsers对象中取出是fromUserName主管的对象实例
- 如果查找出主管对象的实例,将其保存到jBPM环境的变量approver_actors中,同时将变量fromUserName的值设置为找到的主管的名称,并将主管所属的职位存入变量employeePostionId中,以“找到审批人”的转换离开节点
- 反之,如果未找到主管,直接以“找不到审批人”的转换离开节点
关键方法描述:
- executionContext.getVariable(String variableName) 从jBPM上下文中取得变量的值,取得变量值之后需要进行类型的转换
- executionContext.setVariable(String variableName, Object objectName) 将变量的值设置到jBPM的上下文环境中,供流程中的后面节点使用
- executionContext.leaveNode(String transitonName) 离开正在执行的节点,并转换到参数中指定的转换
- executionContext.getJbpmContext().getSession().createQuery(String hsqlQueryStatement) 从jBPM的上下文环境中取得一个会话并创建HSQL查询
五,“审批单据”任务节点处理
当节点进入的时候触发事件:node-enter,这时执行动作处理类:com.hand.bpm.approve.demo.TaskCreator,它同样需要实现接口org.jbpm.graph.def.ActionHandler方法:
1 | void execute( ExecutionContext executionContext ) throws Exception; |
TaskCreator代码逻辑:
- 取得当前节点信息,并循环处理任务节点下的任务(一个任务节点下可以定义多个任务)
- 从jBPM的环境中取得变量approver_actors的值,变量中存放的是审批人的DemoUsers对象实例列表
- 循环approver_actors的对象实例(可以是多个审批人),通过任务实例管理器依次为各审批人创建任务实例,并设置执行人为approver_actors对象实例的审批人
- 如果没有创建任何的任务实例,抛出错误异常
关键方法描述:
- TaskNode taskNode = (TaskNode)executionContext.getNode() 取得执行Java代码的节点
- taskNode.getTasks() 取得任务节点下的任务列表
- executionContext.getToken() 取得流程执行的令牌
- executionContext.getTaskMgmtInstance() 取得任务管理实例,所有的任务实例由它进行创建和管理
- taskMgntInstance.createTaskInstance(task, token) 为任务创建任务实例
- taskInstance.setActorId(actorId) 创建完任务实例后,为任务实例分配执行者
六,任务实例创建工厂实现
上一节中最后通过调用taskMgntInstance.createTaskInstance(task, token)方法来创建任务实例,如果启用了任务实例创建工厂实现,那么任务管理实例会自动去根据启用的工厂来生产一个任务实例,否则按照默认的方式创建一个任务实例。
而在我们本示例的审批工作流中,在分配任务实例给审批人的时候是希望为审批人创建一个待办事项,因此需要实现工厂来插入待办任务到demo_todo_tasks表中
实现步骤:
- 编写任务实例类
- 编写任务实例工厂,通过任务实例类生成任务的实例
- 编写任务实例类对应的Hibernate持久层对象,通过继承来实现
- 在jbpm.cfg.xml配置文件中启用Bean:jbpm.task.instance.factory将其指向实例工厂
任务实例类:com.hand.bpm.approve.demo.ApproveTaskInstance
- 必须继承TaskInstance的默认构造函数
- 在setActorId(String actorId, boolean overwriteSwimlane)方法中通过Hibernate的实体DemoTodoTasks来插入一个待办事项
任务实例工厂
- 从jBPM上下文中取得fromUserName变量的值
- 为fromUserName实例化一个任务实例
七,“权限检查”节点处理
节点对应的动作处理类为:com.hand.bpm.approve.demo.CheckAuthority,它同样需要实现接口org.jbpm.graph.def.ActionHandler方法:
1 | void execute( ExecutionContext executionContext ) throws Exception; |
CheckAuthority代码逻辑:
- 从jBPM上下文参数employeePostionId中取得审批人的职位ID
- 使用HSQL根据审批人职位ID从demo_control_rules表中取得职位的最大审批金额
- 从jBPM上下文参数documentTotalAmount中取得单据的总金额
- 对比职位能够审批的最大金额和单据的总金额,如果单据金额在可以审批的范围内,以“足够”转换离开节点;否则以“不够”转换离开节点
–
相关文章:
