1、描述
Java服务任务用于调用外部Java类。
2、图形表示法
服务任务可视化为圆角矩形,左上角有一个小齿轮图标,如下图:
3、XML表示
有三种方法声明如何调用Java逻辑,下面分别介绍:
- 调用固定的类
使用flowable:class属性提供全限定类名(fully qualified classname),指定流程执行时调用的类,该类必须实现JavaDelegate或ActivityBehavior接口。
<serviceTask id="javaService" flowable:class="com.nbcio.modules.flowable.service.MyJavaDelegate" />
- 调用动态类
使用flowable:delegateExpression属性提供委托代理对象(delegation object)的表达式。该功能和flowable:class类似,同样需要实现JavaDelegate或ActivityBehavior接口,只不过这里不是指定一个具体的实现类,而是查询指定名称的Bean对象。
<serviceTask id="javaService" flowable:delegateExpression="${myDelegateExpressionBean}" />
myDelegateExpressionBean
是一个实现了JavaDelegate
接口的bean,定义在Spring容器中。
- 调用类的指定方法或属性值
使用flowable:expression属性指定类的方法或属性值。同样的,该类需要实现JavaDelegate或ActivityBehavior接口。
<serviceTask id="javaService" flowable:expression="${test.printMessage()}" />
将在名为test
的对象上调用printMessage
方法(不带参数)。当然也可以为表达式中使用的方法传递变量。
属性值示例:
<serviceTask id="javaService" flowable:expression="${test.ready}" />
会调用名为test
的bean的ready
参数的getter方法,getReady
(不带参数)。该值会被解析为执行的流程变量。
4、 vue前端实现
ServiceTask.vue代码如下:
<template> <div class="panel-tab__content"> <el-form size="mini" label-width="90px" @submit.native.prevent> <el-form-item label="服务类型"> <el-select v-model="serviceType"> <el-option v-for="i in Object.keys(typeObject)" :key="i" :label="typeObject[i]" :value="i" /> </el-select> </el-form-item> <el-form-item v-if="serviceType === 'class'" label="Java类"> <el-input v-model="serviceValue" clearable @change="updateInfo('class')" /> </el-form-item> <el-form-item v-if="serviceType === 'expression'" label="表达式"> <el-input v-model="serviceValue" clearable @change="updateInfo('expression')" /> </el-form-item> <el-form-item v-if="serviceType === 'delegateExpression'" label="代理表达式"> <el-input v-model="serviceValue" clearable @change="updateInfo('delegateExpression')" /> </el-form-item> <el-form-item v-if="serviceType === 'expression'" label="结果变量"> <el-input v-model="resultVariable" clearable @change="updateInfo('resultVariable')" /> </el-form-item> </el-form> </div> </template> <script> export default { name: "ServiceTask", props: { id: String, type: String }, inject: { prefix: "prefix", width: "width" }, data() { return { typeObject: { class: "Java 类", expression: "表达式", delegateExpression: "代理表达式" }, serviceType: "", serviceValue: "", resultVariable: "" }; }, watch: { id: { immediate: true, handler(val) { this.$nextTick(() => this.resetBaseInfo()); } } }, methods: { resetBaseInfo() { this.bpmnElement = window?.bpmnInstances?.bpmnElement; var val = ""; if ((val = this.bpmnElement.businessObject.class)) { this.serviceType = "class"; } else if ((val = this.bpmnElement.businessObject.expression)) { this.serviceType = "expression"; if(this.bpmnElement.businessObject.hasOwnProperty('resultVariable')) { this.resultVariable = this.bpmnElement.businessObject.resultVariable; } } else if ((val = this.bpmnElement.businessObject.delegateExpression)) { this.serviceType = "delegateExpression"; } this.serviceValue = val; }, updateInfo(key) { const attrObj = Object.create(null); attrObj.class = undefined; attrObj.expression = undefined; attrObj.delegateExpression = undefined; attrObj.resultVariable = undefined; if (key === "class") { attrObj.class = this.serviceValue; } else if (key === "expression") { attrObj.expression = this.serviceValue; if(this.resultVariable != "") { attrObj.resultVariable = this.resultVariable; } } else if (key === "delegateExpression"){ attrObj.delegateExpression = this.serviceValue; } window.bpmnInstances.modeling.updateProperties(this.bpmnElement, attrObj); } }, beforeDestroy() { this.bpmnElement = null; } }; </script>
5、后端java实现
5.1 具体实现实例
下面是一个Java类的示例,用于将流程变量String改为大写。这个类通过实现org.flowable.engine.delegate.JavaDelegate接口,可以在流程执行中被调用。
同时,需要重写execute(DelegateExecution)方法实现业务逻辑。这个方法就是引擎将调用的方法。另外,通过该方法中的DelegateExecution参数可以访问流程实例的各种信息。
public class ToUppercase implements JavaDelegate { public void execute(DelegateExecution execution) { String var = (String) execution.getVariable("input"); var = var.toUpperCase(); execution.setVariable("input", var); } }
如果实现org.flowable.engine.impl.delegate.ActivityBehavior接口,可以访问更强大的引擎功能,例如,可以影响流程的控制流程。但注意这并不是好的实践,需要避免这么使用。
5.2 任务的返回值
服务执行的返回值(仅对使用表达式的服务任务),可以通过为服务任务定义的'flowable:resultVariable'属性设置为流程变量。可以是已经存在的,或者新的流程变量。 如果指定为已存在的流程变量,则流程变量的值会被服务执行的返回值覆盖。 如果不指定结果变量名,则服务任务的返回值将被忽略。
<serviceTask id="ExpressionServiceTask" flowable:expression="${myService.doing()}" flowable:resultVariable="myVariable" />
在上例中,服务执行的结果(调用'doing()'方法的返回值),在服务执行完成后,会设置为名为'myVariable'的流程变量。
6、效果图