表达语言
Camunda BPM支持统一表达语言(EL),它是JSP 2.1标准(JSR-245)的一部分。因此,它使用开源的JUEL实现。要获得有关表达式语言用法的更多常规信息,请阅读官方文档。特别是提供的示例很好地概述了表达式的语法。
在Camunda BPM中,EL可在许多情况下用于评估类似脚本的小型表达式。下表概述了支持EL使用的BPMN元素。
BPMN元素 | EL支持 |
---|---|
服务任务,业务规则任务,发送任务,消息中间抛出事件,消息结束事件,执行侦听器和任务侦听器 | 表达语言作为委派代码 |
顺序流 | 表达语言作为序列流的条件表达 |
所有任务,所有事件,事务,子流程和连接器 | inputOutput参数映射内的表达式语言 |
不同元素 | 表达语言作为属性或元素的值 |
所有流程节点,流程定义 | 表达语言,以确定工作的优先级 |
表达语言的用法
委托代码
除了Java代码,Camunda BPM还支持将表达式评估为委派代码。有关委派代码的一般信息,请参见相应 部分。
当前支持两种类型的表达式:camunda:expression
和 camunda:delegateExpression
。
用camunda:expression
它可以评价值表达或以调用一个方法表达。您可以使用表达式或Spring和CDI bean中可用的特殊变量。有关变量和Spring以及CDI bean的更多信息,请参见相应的部分。
<process id="process">
<extensionElements>
<!-- execution listener which uses an expression to set a process variable -->
<camunda:executionListener event="start" expression="${execution.setVariable('test', 'foo')}" />
</extensionElements>
<!-- ... -->
<userTask id="userTask">
<extensionElements>
<!-- task listener which calls a method of a bean with current task as parameter -->
<camunda:taskListener event="complete" expression="${myBean.taskDone(task)}" />
</extensionElements>
</userTask>
<!-- ... -->
<!-- service task which evaluates an expression and saves it in a result variable -->
<serviceTask id="serviceTask"
camunda:expression="${myBean.ready}" camunda:resultVariable="myVar" />
<!-- ... -->
</process>
该属性camunda:delegateExpression
用于计算为委托对象的表达式。该委托对象必须实现JavaDelegate
orActivityBehavior
接口。
<!-- service task which calls a bean implementing the JavaDelegate interface -->
<serviceTask id="task1" camunda:delegateExpression="${myBean}" />
<!-- service task which calls a method which returns delegate object -->
<serviceTask id="task2" camunda:delegateExpression="${myBean.createDelegate()}" />
注:主要用于监听器和服务任务中
条件
要使用条件序列流,通常使用表达语言。因此, 必须使用conditionExpression
这种类型的顺序流元素tFormalExpression
。元素的文本内容是要评估的表达式。
在表达式内部,有一些特殊的变量可用于访问当前上下文。要查找有关可用变量的更多信息,请参见相应部分。
以下示例显示了将表达式语言用作顺序流的条件的情况:
<sequenceFlow>
<conditionExpression xsi:type="tFormalExpression">
${test == 'foo'}
</conditionExpression>
</sequenceFlow>
inputOutput参数
使用CamundainputOutput
扩展元素,您可以映射inputParameter
或outputParameter
表达式语言。
在表达式内部,有一些特殊的变量可用于访问当前上下文。要查找有关可用变量的更多信息,请参见相应部分。
以下示例显示了一个inputParameter
使用表达式语言来调用Bean方法的。
<serviceTask id="task" camunda:class="org.camunda.bpm.example.SumDelegate">
<extensionElements>
<camunda:inputOutput>
<camunda:inputParameter name="x">
${myBean.calculateX()}
</camunda:inputParameter>
</camunda:inputOutput>
</extensionElements>
</serviceTask>
表达式语言中变量和函数的可用性
过程变量
当前作用域的所有过程变量都可以在表达式内直接使用。因此,条件序列流可以直接检查变量值:
<sequenceFlow>
<conditionExpression xsi:type="tFormalExpression">
${test == 'start'}
</conditionExpression>
</sequenceFlow>
内部上下文变量
根据当前的执行上下文,在评估表达式时可以使用特殊的内置上下文变量:
变量 | Java类型 | 语境 |
---|---|---|
execution |
DelegateExecution |
在BPMN执行上下文中可用,例如服务任务,执行侦听器或序列流。 |
task |
DelegateTask |
在任务上下文(如任务侦听器)中可用。 |
caseExecution |
DelegateCaseExecution |
在CMMN执行上下文中可用。 |
authenticatedUserId |
String |
当前经过身份验证的用户的ID。仅当通过的相应方法设置了当前认证用户的ID时,才返回一个值 IdentityService 。否则返回null 。 |
下面的示例显示一个表达式,该表达式将变量设置为test
执行侦听器的当前事件名称。
<camunda:executionListener event="start"
expression="${execution.setVariable('test', execution.eventName)}" />
注:在流程开启异步后,在异步线程中可能无法通过authenticatedUserId
为null,已证实,下面为解决方案
官方社区里给出的解决方案:https://forum.camunda.org/t/identityservice-getcurrentauthentication-is-null-after-timer-boundary-event/15263
就是在创建用户任务时,将id存储到过程变量中,通过execution.getVariable(id)
或task.getVariable(id)
获取
使用Spring和CDI的外部上下文变量
如果流程引擎与Spring或CDI集成在一起,则可以在表达式内部访问Spring和CDI Bean。 有关更多信息,请参见Spring和CDI的相应部分。以下示例显示了将JavaDelegate
接口实现为委托执行的bean的用法 。
<serviceTask id="task1" camunda:delegateExpression="${myBean}" />
使用expression属性,可以调用Bean的任何方法。
<serviceTask id="task2" camunda:expression="${myBean.myMethod(execution)}" />
内部上下文功能
评估表达式时,可以使用特殊的内置上下文函数:
功能 | 返回类型 | 描述 |
---|---|---|
currentUser() |
String |
返回当前已认证用户的用户标识,或者当前null 没有用户通过认证。 |
currentUserGroups() |
List of Strings |
返回当前已认证用户的组ID列表,或者null 如果当前没有用户授权,则返回该组ID的列表。 |
now() |
Date |
以Java Date对象的形式返回当前日期。 |
dateTime() |
DateTime |
返回当前日期的Joda-Time DateTime对象。 有关所有可用功能,请参阅 Joda-Time文档。 |
以下示例将用户任务的截止日期设置为任务创建后的3天。
<userTask id="theTask" name="Important task" camunda:dueDate="${dateTime().plusDays(3).toDate()}"/>
注:在流程开启异步后,在异步线程中可能无法通过currentUser()
获取用户信息,未做证实