执行监听器允许您在流程执行期间发生特定事件时执行外部Java代码或评估表达式。可以捕获的事件是:

  • 开始和结束一个流程实例。
  • 转型。
  • 开始和结束活动。
  • 开始和结束一个网关。
  • 开始和结束中间事件。
  • 结束开始事件并开始结束事件。

以下流程定义包含3个执行监听器:

<process id="executionListenersProcess">
<extensionElements>
<flowable:executionListener
class="org.flowable.examples.bpmn.executionlistener.ExampleExecutionListenerOne"
event="start" />
</extensionElements>
<startEvent id="theStart" />
<sequenceFlow sourceRef="theStart" targetRef="firstTask" />
<userTask id="firstTask" />
<sequenceFlow sourceRef="firstTask" targetRef="secondTask">
<extensionElements>
<flowable:executionListener
class="org.flowable.examples.bpmn.executionListener.ExampleExecutionListenerTwo" />
</extensionElements>
</sequenceFlow>
<userTask id="secondTask" >
<extensionElements>
<flowable:executionListener
expression="${myPojo.myMethod(execution.event)}"
event="end" />
</extensionElements>
</userTask>
<sequenceFlow sourceRef="secondTask" targetRef="thirdTask" />
<userTask id="thirdTask" />
<sequenceFlow sourceRef="thirdTask" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>

当进程启动时通知第一个执行监听器。监听器是一个外部的Java类(ExampleExecutionListenerOne)并且应该实现一个org.flowable.engine.delegate.ExecutionListener接口。事件发生时(在这种情况end下),该方法notify(ExecutionListenerExecution execution)被调用。

public class ExampleExecutionListenerOne implements ExecutionListener {
	public void notify(ExecutionListenerExecution execution) throws Exception {
		execution.setVariable("variableSetInExecutionListener", "firstValue");
		execution.setVariable("eventReceived", execution.getEventName());
	}
}

也可以使用实现org.flowable.engine.delegate.JavaDelegate接口的委托类。这些委托类可以在其他结构中重用,例如serviceTask的委托。

第二个执行监听器在进行转换时被调用。请注意,该listener元素没有定义一个event,因为只有在take事件过渡。在event转换中定义侦听器时,属性中的值将被忽略。

活动secondTask结束时会调用最后一个执行侦听器。而不是class在侦听器声明中使用,而是expression定义了一个,当事件被触发时,a 被评估/调用。

<flowable:executionListener expression="${myPojo.myMethod(execution.eventName)}" event="end" />

和其他表达式一样,执行变量也被解析并可以被使用。由于执行实现对象具有公开事件名称的属性,因此可以将事件名称传递给您的方法execution.eventName。

执行监听器也支持使用a delegateExpression,类似于服务任务。

<flowable:executionListener event="start" delegateExpression="${myExecutionListenerBean}" />

后来,我们还引入了一种新的执行监听器,org.flowable.engine.impl.bpmn.listener.ScriptExecutionListener。此脚本执行监听器允许您为执行监听器事件执行一段脚本逻辑。

<flowable:executionListener event="start"
class="org.flowable.engine.impl.bpmn.listener.ScriptExecutionListener">
<flowable:field name="script">
<flowable:string>
def bar = "BAR"; // local variable
foo = "FOO"; // pushes variable to execution context
execution.setVariable("var1", "test"); // test access to execution instance
bar // implicit return value
</flowable:string>
</flowable:field>
<flowable:field name="language" stringValue="groovy" />
<flowable:field name="resultVariable" stringValue="myVar" />
</flowable:executionListener>

执行监听器上的字段注入

当使用配置了class属性的执行监听器时,可以应用字段注入。这与服务任务字段注入中使用的机制完全相同,其中包含字段注入提供的可能性的概述。

下面的代码片段显示了一个简单的示例流程,带有一个注入了字段的执行监听器。

<process id="executionListenersProcess">
<extensionElements>
<flowable:executionListener
class="org.flowable.examples.bpmn.executionListener.ExampleFieldInjectedExecutionListener"
event="start">
<flowable:field name="fixedValue" stringValue="Yes, I am " />
<flowable:field name="dynamicValue" expression="${myVar}" />
</flowable:executionListener>
</extensionElements>
<startEvent id="theStart" />
<sequenceFlow sourceRef="theStart" targetRef="firstTask" />
<userTask id="firstTask" />
<sequenceFlow sourceRef="firstTask" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
public class ExampleFieldInjectedExecutionListener implements ExecutionListener {
	private Expression fixedValue;
	private Expression dynamicValue;
	public void notify(ExecutionListenerExecution execution) throws Exception {
		execution.setVariable("var", fixedValue.getValue(execution).toString() +
		dynamicValue.getValue(execution).toString());
	}
}

类ExampleFieldInjectedExecutionListener连接两个注入字段(一个固定另一个动态)并将其存储在过程变量中var。

@Deployment(resources = {
"org/flowable/examples/bpmn/executionListener/ExecutionListenersFieldInjectionProcess.bpmn20.xml"})
public void testExecutionListenerFieldInjection() {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("myVar", "listening!");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
"executionListenersProcess", variables);
Object varSetByListener = runtimeService.getVariable(processInstance.getId(), "var");
assertNotNull(varSetByListener);
assertTrue(varSetByListener instanceof String);
// Result is a concatenation of fixed injected field and injected expression
assertEquals("Yes, I am listening!", varSetByListener);
}

上面文章来自盘古BPM研究院:http://vue.pangubpm.com/
文章翻译提交:https://github.com/qiudaoke/flowable-userguide
了解更多文章可以关注微信公众号:
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐