在使用流程的时候,很多时候我们需要在流程的执行过程中获取流程的当前信息,比如任务信息,流程定义信息,流程实例信息等。然后根据这些信息采取相关的操作。我们主动的去做这些操作是非常不方便的。我像大家介绍两种方法,这两种方式都是基于观察者模式的,将主动获取信息,变成被动推送信息。首先介绍一种使用AssignmentHandler的方式。
AssignmentHandler是任务分配的一个接口。需要我们去实现它。然后在配置文件配置。
1:在jpdl文件中配置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>
- lt;/assignment-handler>
- <transition name="通过审批" to="结束" g="-62,-25"/>
- </task>
2:编写自己的AssignmentHandler类实现AssignmentHandler接口。
- 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的灵活性,为我们提供了很多方便。