在JBPM的使用中,很多时候我们要用到监听,前面讲过一个AssignmentHandler,它的作用更多的被用在动态分配任务中。AssignmentHandler虽然也能实现监听,但是有它的不足只出。它只能放到Task节点下,作为任务分配来使用。其它节点就不能用了。其它节点不会触发AssignmentHandler的方法。
在其它节点下监听流程信息,采取用户操作一般使用EventListener,EventListener可以放到任务节点下,不如process根目录,end节点,task,state等节点。当有流程经过这个节点的时候就会出发节点事件所注册的类。
为了给一个流程或一个活动分配一系列的事件监听器,使用on元素来为事件监听器分组并指定事件。
下面看一个我的实例:
1:JPDL语言定义Event和注册EventListener类。
- <end g="319,369,48,48" name="结束">
- <on event="start">
- <event-listener class="com.zhjy.bpm.Listener.EndListener">
- </event-listener>
- </on>
- </end>
这个监听是在End节点中注册一个监听类,这个类是我们自己写的。使用on元素来指定事件,这个需要注意的是on元素event属性可以配置为start或者end,这个为告诉jbpm这个事件是在end的开始执行开始完成执行。
2:编写Listener类。
- import org.jbpm.api.listener.EventListener;
- import org.jbpm.api.listener.EventListenerExecution;
- import org.jbpm.pvm.internal.env.EnvironmentImpl;
- import com.zhjy.mtdev.plan.PlanState;
- import com.zhjy.mtdev.plan.service.IPlanService;
- /**
- * @Title: TaskListener.java
- * @author 李守宏
- * @date 2012-9-18 下午02:05:00
- * @version V1.0
- */
- public class EndListener implements EventListener {
- private static final long serialVersionUID = 1L;
- /* (non-Javadoc)
- * @see org.jbpm.api.listener.EventListener#notify(org.jbpm.api.listener.EventListenerExecution)
- */
- @Override
- public void notify(EventListenerExecution execution) throws Exception {
- IPlanService planService= (IPlanService) EnvironmentImpl.getFromCurrent("planService");
- String ownerId = execution.getVariable("planId").toString();
- String sign = execution.getVariable("sign").toString();
- if("通过".equals(sign)){
- planService.updateState(ownerId, PlanState.STORAGE.toString());
- }else if("补正".equals(sign)){
- planService.updateState(ownerId, PlanState.CORRECT.toString());
- }else{
- planService.updateState(ownerId, PlanState.REJECT.toString());
- }
- }
- }
这里的notify方法是必须实现的。流程通过则触发这个事件,然后可以拿到流程执行的相关信息,通过execution可以获取流程信息,流程实例信息,甚至是任务信息,任务信息获取的方式是这样的。
- TaskService taskService= (TaskService) EnvironmentImpl.getFromCurrent("taskService");
- //获取流程ID
- String id = execution.getProcessInstance().getId();
- List<Task> task = taskService.createTaskQuery().processInstanceId(id).list();
拿到Task列表以后,你就可以拿到很多信息。但是一定注意,在Task中获取已经存在的一个TaskID,然后去完成它会报错的。因为这个监听的过程中旧的任务ID已经不存在新的任务ID还没有生成,task是为空的。这个大家一定要注意,我在这块研究了很长时间。
总之上面说的两种监听,是jbpm常用的获取流程信息的方法,这样被动的监听信息,比主动的获取信息要方便很多,这是对观察者模式的良好应用。监听还可以结合其它技术使用,达到更好的效果比如泳道
SWIMLANE 等。达到任务的动态分配效果。