在使用流程的时候,很多时候我们需要在流程的执行过程中获取流程的当前信息,比如任务信息,流程定义信息,流程实例信息等。然后根据这些信息采取相关的操作。我们主动的去做这些操作是非常不方便的。我像大家介绍两种方法,这两种方式都是基于观察者模式的,将主动获取信息,变成被动推送信息。首先介绍一种使用AssignmentHandler的方式。
AssignmentHandler是任务分配的一个接口。需要我们去实现它。然后在配置文件配置。
我们在task节点中可以使用它为。配置方式如下:其中field是一个变量,可以在流程执行到这里的时候拿到这个参数的value。也可以动态改变这个value。
<task assignee="pzhuren" name="主任审批" g="186,291,92,52"> <assignment-handler class="com.zhjy.bpm.Listener.TaskListener"> <field name="msg"> <string value="PLAN"/> </field> </assignment-handler> <transition name="通过审批" to="结束" g="-62,-25"/> </task>
package com.zhjy.bpm.Listener; import java.util.Date; import org.jbpm.api.TaskService; import org.jbpm.api.model.OpenExecution; import org.jbpm.api.task.Assignable; import org.jbpm.api.task.AssignmentHandler; import org.jbpm.pvm.internal.env.EnvironmentImpl; import org.jbpm.pvm.internal.task.OpenTask; import com.zhjy.mtdev.wibox.taskins.ProcessWorkState; import com.zhjy.mtdev.wibox.taskins.WorkerType; import com.zhjy.mtdev.wibox.taskins.dao.IProjectProcessWorkersDAO; import com.zhjy.mtdev.wibox.taskins.domain.IProjectProcessWorkers; import com.zhjy.mtdev.wibox.taskins.domain.hibernate.ProjectProcessWorkersHibernate; import com.zhjy.mtdev.wibox.taskins.service.IProjectTaskInsService; /** * @Title: TaskListener.java * @Package com.zhjy.bpm.test.Listener * @author 李守宏 * @date 2012-9-18 下午02:05:00 * @version V1.0 */ public class TaskListener implements AssignmentHandler { private String msg; private static final long serialVersionUID = 1L; @Override public void assign(Assignable assignable, OpenExecution execution) throws Exception { IProjectProcessWorkers processWorkers = new ProjectProcessWorkersHibernate(); TaskService taskService = (TaskService) EnvironmentImpl .getFromCurrent("taskService"); IProjectTaskInsService taskInsService = (IProjectTaskInsService) EnvironmentImpl .getFromCurrent("projectTaskInsService"); OpenTask task = (OpenTask) assignable; String taskId = task.getId(); // 设置参数 processWorkers.setCreateDate(new Date()); // 这里直接拿到流程的key值作为项目计划ID,因为项目计划提交到流程的时候,要设置一个key值,也就是计划的project_plan_id到流程实例中 // String ownerId = execution.getKey().toString(); /* * if(taskService.getVariable(taskId, "ownerId").toString() == "" ){ * ownerId = }else{ ownerId = taskService.getVariable(taskId, * "ownerId").toString(); } */ String ownerId = execution.getVariable("planId").toString(); processWorkers.setOwnerId(ownerId); // 这个计划类型,直接从jbdl的流程变量msg中获取 processWorkers.setOwnerType(msg); // 流程定义ID processWorkers.setProcessId(execution.getId()); // 更新状态为已完成 对应的是执行中 processWorkers.setState(ProcessWorkState.DOING.toString()); // 这个任务接受人ID要提前在jbdl中配置,使用它的getAssignee processWorkers.setWorkerId(task.getAssignee()); processWorkers.setWorkerType(WorkerType.JOBROLE.toString()); processWorkers.setWorkId(taskId); //后来加入的四个字段 //1:workName;工作任务名称(所在节点名称) processWorkers.setWorkName(task.getActivityName().toString()); //2:前置工作ID prevId 从变量获取 processWorkers.setPrevId(execution.getVariable("prevId").toString()); taskInsService.addProcessWork(processWorkers); } /** * @param msg * the msg to set */ public void setMsg(String msg) { this.msg = msg; } }
这里是我使用AssignmentHandler 实现获取流程信息,然后插入一条新数据的实例。其中assign是必须实现的,这里面的两个参数是最重要的,根据这两个参数,可以获取流程的很多信息。比如流程定义,流程实例,流程任务等。
注意OpenTask task= (OpenTask) assignable;这句话是关键,你可以把assignable强制转换成task,因为他实现了task接口。这样你就可以拿到任务信息了。这块是这个方法的核心,是我花费了很大精力,通过研究jbpm源码才弄明白的。这块网上还没有见到这种做法。
jbpm有很多的监听,这个只是其中一个,监听大大提升了jbpm的灵活性,为我们提供了很多方便。