activiti学习10任务监听器的使用

activiti提供了任务监听器,允许在任务执行的过程中执行特定的java程序或者表达式,目前任务监听器只能在user task中使用。在流程定义文件中通过为bpmn 2.0 的元素extensionElements添加activiti:taskListener 子元素来定义一个任务监听。任务监听器不是bpmn规范的内容,是activiti对其的扩展。

一、使用class指定监听器

在流程文件中,可以使用activiti:taskListener元素的class属性来指定监听器的java类,使用这种方式,监听器类必须实现org.activiti.engine.delegate.TaskListener 接口

自定义监听器类

public class MyListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("自定义任务监听器执行了");
    }
}

其中DelegateTask是一个接口,通过该接口可以操作当前的user task对象

在流程定义文件中用class属性来指定该监听器

 <userTask id="sid-03CF0A31-4FD4-4F04-90BA-72785636060C" name="用class属性指定任务监听器">
      <extensionElements>
        <activiti:taskListener event="create"                       
                               class="com.lyy.activiti_listener.MyListener">
        </activiti:taskListener>
      </extensionElements>
    </userTask>

这样就通过class属性给一个用户任务指定了一个任务监听器,当流程执行到这个用户任务时,该任务监听器就会被执行。

二、使用expression来指定监听器

使用activiti:taskListener元素的expression属性来指定监听器

通过juel表达式指定某个java类中的公共方法,这个java类需要实现序列化接口,把它的对象放在流程变量中,如果整合了spring,也可以是spring容器中的bean

<userTask id="sid-E3A5B9D7-1985-4A8B-987F-F9B1589AA27A" name="使用expression指定监听器">
      <extensionElements>
        <activiti:taskListener event="create" expression="${myListener.execute(task)}">
          </activiti:taskListener>
      </extensionElements>
    </userTask>

上面这个用户任务,使用expression属性指定了监听器的juel表达式,表示执行myListener这个对象的execute方法。参数task是DelegateTask类型的,可以用来操作当前任务。下边是对应的任务监听器

//@Component("myListener")
public class MyListener2 implements Serializable {

    public void execute(DelegateTask delegateTask){
        System.out.println("使用表达式来指定监听器");
    }
}

当流程执行到这个任务时,可以在流程变量中放一个名为myListener的变量,值是自定义监听器的对象。

Map<String,Object> map=new HashMap<>();
map.put("myListener",new MyListener2());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);

也可以把上边的这个监听器加入spring容器中,指定bean名称为myListener

这样当这个任务创建后就会执行监听器代码。

三、使用delegateExpression指定监听器

也可以使用delegateExpression 配合juel表达式指定任务监听器,对应的监听器类要实现TaskListener和序列化接口。假如juel表达式配置${myTaskListener3},activiti会从流程中查找名称为myTaskListener3的流程变量,并执行其notify方法。

监听器的代码如下

public class MyListener3 implements TaskListener,Serializable {
    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("使用delegateExpression来指定监听器");
    }
}

在流程定义文件中配置监听器

<userTask id="sid-091EB299-76A8-4DBD-A1A5-50F0E25B97DA" name="使用delegateExpression指定监听器">
	    <extensionElements>
            <activiti:taskListener event="create" delegateExpression="${myTaskListener3}">
			</activiti:taskListener>
        </extensionElements>
	</userTask>

在流程到达该任务节点时,就会从流程变量中获取myTaskListener3,并执行notify方法

四、监听器的触发

任务监听器会在任务的不同事件中被触发,包括任务创建(create),任务完成(complete),指定代理人(assignment),通过activiti:taskListener的event属性来指定监听器的触发事件。

像上边的几个例子,都是使用的create事件。

需要注意的是,一个用户任务可以配置多个监听器,这种情况下assignment事件的监听器会比create先执行,因为指定任务代理人属于任务创建过程的一部分,create事件只有当任务的所有数据都写入到数据库后才会触发。

五、总结

对三种指定监听器的方式进行一个比较,

(1) class方式,监听器只需要实现TaskListener接口,不需要在流程变量中加入监听器类的对象

(2)expression方式,监听器可以是一个普通的java类,但要实现序列化接口,需要在流程变量中加入监听器类的对象,或者加入spring容器中

(3)delegateExpression,监听器要同时实现TaskListener和序列化接口,需要在流程变量中加入监听器类的对象