Flowable入门系列文章12 - Flowable API 02
Posted 分享牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flowable入门系列文章12 - Flowable API 02相关的知识,希望对你有一定的参考价值。
1、变量
每个流程实例都需要并使用数据来执行它所组成的步骤。在Flowable中,这个数据被称为变量,它们被存储在数据库中。在调用外部服务(例如提供输入或存储服务调用的结果)时,变量可用于表达式中(例如,在专用网关中选择正确的传出序列流),在Java服务任务中。
流程实例可以包含变量(称为流程变量),也可以包含执行(特定指针指向流程激活的地方),用户任务可以包含变量。一个流程实例可以有任意数量的变量。每个变量都存储在ACT_RU_VARIABLE数据库表中的一行中。
所有startProcessInstanceXXX方法都有一个可选参数,用于在创建和启动流程实例时提供变量。例如,从RuntimeService:
ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);
变量可以在流程执行过程中添加。例如(RuntimeService):
void setVariable(String executionId, String variableName, Object value);
void setVariableLocal(String executionId, String variableName, Object value);
void setVariables(String executionId, Map<String, ? extends Object> variables);
void setVariablesLocal(String executionId, Map<String, ? extends Object> variables);
需要注意的是变量,可以设置本地对于给定的执行(记住,流程实例包括执行的树)。该变量只在该执行中可见,在执行树中不会更高。如果数据不应该传播到流程实例级别,或者变量在流程实例中具有某个特定路径的新值(例如,在使用并行路径时),这可能很有用。
变量也可以被检索,如下所示。请注意,TaskService上存在类似的方法。这意味着任务(如执行)可以具有仅在任务期间处于活动状态的局部变量。
Map<String, Object> getVariables(String executionId);
Map<String, Object> getVariablesLocal(String executionId);
Map<String, Object> getVariables(String executionId, Collection<String> variableNames);
Map<String, Object> getVariablesLocal(String executionId, Collection<String> variableNames);
Object getVariable(String executionId, String variableName);
<T> T getVariable(String executionId, String variableName, Class<T> variableClass);
变量通常用于Java委托,表达式,执行或任务监听器,脚本等等。在这些结构中,当前执行或任务对象是可用的,并且可以用于可变设置和检索。最简单的方法是这些:
execution.getVariables();
execution.getVariables(Collection<String> variableNames);
execution.getVariable(String variableName);
execution.setVariables(Map<String, object> variables);
execution.setVariable(String variableName, Object value);
请注意,以上所有内容也适用于本地变体。
对于历史(和向后兼容的原因),当进行上述任何调用时,幕后所有变量将从数据库中获取。这意味着如果你有10个变量,但是只通过getVariable(“myVariable”)得到一个变量,幕后的其他9 个变量将被获取和缓存。这不一定是不好的,因为随后的调用不会再次访问数据库。例如,当你的流程定义有三个连续的服务任务(从而一个数据库事务)时,使用一个调用来获取第一个服务任务中的所有变量可能会更好,然后单独获取每个服务任务中所需的变量。请注意,这适用于既用于获取和设置变量。
当然,当使用很多变量或者只是想要严格控制数据库查询和流量时,这是不合适的。已经引入了其他方法来对此进行更严格的控制,方法是添加具有可选参数的新方法,以告知引擎是否提取并缓存所有变量:
Map<String, Object> getVariables(Collection<String> variableNames, boolean fetchAllVariables);
Object getVariable(String variableName, boolean fetchAllVariables);
void setVariable(String variableName, Object value, boolean fetchAllVariables);
当对参数fetchAllVariables使用true时,行为将如上所述:当获取或设置变量时,所有其他变量将被获取并缓存。
但是,使用false作为值时,将使用特定的查询,并且不会提取或缓存其他变量。只有这里讨论的变量的值才会被缓存以供后续使用。
2、瞬态变量
瞬态变量是像常规变量一样的变量,但不是持久的。通常,瞬态变量用于高级用例。如有疑问,请使用常规的过程变量。
以下内容适用于瞬态变量:
- 对于瞬态变量没有存储历史。
- 像常规变量一样,瞬态变量在设置时放置在最高父节点上。这意味着在执行时设置变量时,瞬态变量实际上存储在流程实例执行中。像常规变量一样,如果在特定执行或任务上设置变量,则会存在方法的本地变体。
- 过程变量只能在流程定义中的下一个等待状态之前被访问。之后,他们走了。在这里,等待状态意味着流程实例中保存到数据存储的点。请注意,异步活动在这个定义中也是一个等待状态!
- 瞬态变量只能由setTransientVariable(name,value)设置,但是在调用getVariable(name)时也会返回瞬态变量(一个getTransientVariable(name)也存在,只能检查瞬态变量)。其原因是为了使表达式的写作变得容易,并且使用变量的现有逻辑适用于这两种类型。
- 一个瞬态变量会隐藏一个具有相同名称的持久变量。这意味着,如果在流程实例上设置了持久变量和瞬态变量,并调用getVariable(“someVariable”),则将返回瞬态变量值。
您可以在常规变量暴露的大多数地方设置和获取瞬态变量:
- 在DelegateExecution在JavaDelegate实现
- 在DelegateExecution在ExecutionListener实现和DelegateTask上TaskListener实现
- 在通过执行对象的脚本任务中
- 通过运行时服务启动流程实例时
- 完成任务时
- 调用runtimeService.trigger方法时
这些方法遵循常规过程变量的命名约定:
void setTransientVariable(String variableName, Object variableValue);
void setTransientVariableLocal(String variableName, Object variableValue);
void setTransientVariables(Map<String, Object> transientVariables);
void setTransientVariablesLocal(Map<String, Object> transientVariables);
Object getTransientVariable(String variableName);
Object getTransientVariableLocal(String variableName);
Map<String, Object> getTransientVariables();
Map<String, Object> getTransientVariablesLocal();
void removeTransientVariable(String variableName);
void removeTransientVariableLocal(String variableName);
下面的BPMN图显示了一个典型的例子:
假设获取数据服务任务调用某个远程服务(例如,使用REST)。我们还假设一些配置参数是需要的,并且在启动流程实例时需要提供。另
外,这些配置参数对于历史审计目的来说并不重要,所以我们将它们作为瞬态变量传递:
ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
.processDefinitionKey("someKey")
.transientVariable("configParam01", "A")
.transientVariable("configParam02", "B")
.transientVariable("configParam03", "C")
.start();
请注意,在用户任务到达并保存到数据库之前,瞬态变量将可用。例如,在“ 附加工作”用户任务中,它们不再可用。另请注意,如果提取数据是异步的,那么在该步骤之后它们将不可用。
在获取数据(简化)可能是这样的:
public static class FetchDataServiceTask implements JavaDelegate {
public void execute(DelegateExecution execution) {
String configParam01 = (String) execution.getVariable(configParam01);
// ...
RestReponse restResponse = executeRestCall();
execution.setTransientVariable("response", restResponse.getBody());
execution.setTransientVariable("status", restResponse.getStatus());
}
}
该过程数据会得到响应瞬态变量,分析它,并存储在实际过程变量的相关数据,我们以后需要它们。
离开专用网关的序列流的条件不知道是否使用了持久变量或瞬变变量(在这种情况下是状态瞬态变量):
<conditionExpression xsi:type="tFormalExpression">${status == 200}</conditionExpression>
上面文章来自盘古BPM研究院:http://vue.pangubpm.com/
文章翻译提交:https://github.com/qiudaoke/flowable-userguide
了解更多文章可以关注微信公众号:
以上是关于Flowable入门系列文章12 - Flowable API 02的主要内容,如果未能解决你的问题,请参考以下文章
Flowable入门系列文章23 - 基本的Flowable概念四
Flowable入门系列文章20 - 基本的Flowable概念一
Flowable入门系列文章80 - Flowable Designer部署功能