乐趣区

关于工作流:Flowable实战八BPMN20-任务

  工作是流程中最重要的组成部分。Flowable 提供了多种工作类型,以满足理论需要。

  罕用工作类型有:

  • 用户工作
  • Java Service 工作
  • 脚本工作
  • 业务规定工作
  • 执行监听器
  • 工作监听器
  • 多实例

  集成扩大的工作类型有:

  • 手动工作
  • Java 接管工作
  • Shell 工作
  • 弥补处理器
  • Web Service 工作
  • 邮件工作
  • Http 工作
  • Camel 工作
  • Mule 工作

  工作的图形都是以一个圆角矩形为根底,在左上角增加具体类型的图标。

一、罕用的工作类型

1.1 用户工作

1.1.1 形容

“用户工作(user task)”指须要人工执行的工作。当流程执行达到用户工作时,流程实例会进行期待,直到用户触发实现工作动作。

1.1.2 图示

  用户工作用左上角有一个小用户图标的规范工作(圆角矩形)示意。

1.1.3 XML 示意

  用户工作在 XML 中如下定义。其中 id 是必须属性,name是可选属性。

    <userTask id="theTask" name="重要工作" />

1.1.4 到期日期

  每个工作都能够设置到期日期(due date)。

  能够指定固定工夫或绝对工夫,比方,当 dueDate 为“PT30M”时,示意达到工作 30 分钟后到期。

  到期日期必须合乎 java.util.Date 或 java.util.String(ISO8601 格局)。

  理论利用,咱们指定为变量值。

    <userTask id="theTask" name="Important task" flowable:dueDate="${dateVariable}"/>

  工作的到期日期能够应用 TaskService,或者在 TaskListener 中应用传递的 DelegateTask 批改。

1.1.5 工作指派

  • 指派确定的办理人
    <userTask id="theTask" name="重要工作" flowable:assignee="jinyangjie"/>
  • 指派潜在办理人
    <userTask id="theTask" name="重要工作" flowable:candidateUsers="jinyangjie, zhangsan" />
  • 指派潜在办理组
    <userTask id="theTask" name="重要工作" flowable:candidateGroups="leader, manager" />

  更多任务指派的内容,已在“用户和组”的篇章中介绍,这里不再赘述。

1.2 Java Service 工作

1.2.1 形容

  Java Service 工作(Java service task)用于调用 Java 类。Java Service 不属于 BPMN2.0 标准,而是 Flowable 的自定义扩大。

1.2.2 图示

  服务工作用左上角有一个小齿轮图标的圆角矩形示意。

1.2.3 XML 示意

  有三种办法申明如何调用 Java 逻辑,上面别离介绍:

  • 调用固定的类

  应用 flowable:class 属性提供全限定类名(fully qualified classname),指定流程执行时调用的类,该类必须实现 JavaDelegate 或 ActivityBehavior 接口。

    <serviceTask id="javaService" flowable:class="com.example.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="#{printer.printMessage()}" />

  将在名为 printer 的对象上调用 printMessage 办法(不带参数)。当然也能够为表达式中应用的办法传递变量。

  属性值示例:

    <serviceTask id="javaService" flowable:expression="#{printer.ready}" />

  会调用名为 printer 的 bean 的 ready 参数的 getter 办法,getReady(不带参数)。该值会被解析为执行的流程变量。

1.2.4 具体实现实例

  上面是一个 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 接口,能够拜访更弱小的引擎性能,例如,能够影响流程的管制流程。但留神这并不是好的实际,须要防止这么应用。

1.2.5 工作的返回值

  服务执行的返回值(仅对应用表达式的服务工作),能够通过为服务工作定义的 ‘flowable:resultVariable’ 属性设置为流程变量。能够是曾经存在的,或者新的流程变量。如果指定为已存在的流程变量,则流程变量的值会被服务执行的返回值笼罩。如果不指定后果变量名,则服务工作的返回值将被疏忽。

    <serviceTask id="aMethodExpressionServiceTask"
        flowable:expression="#{myService.doSomething()}"
        flowable:resultVariable="myVar" />

  在上例中,服务执行的后果(调用 ‘doSomething()’ 办法的返回值),在服务执行实现后,会设置为名为 ‘myVar’ 的流程变量。

1.2.6 异样解决

  当执行自定义逻辑时,通常须要捕捉并在流程中解决特定的业务异样。Flowable 提供了多种形式。

1.2.6.1 抛出 BPMN 谬误

  能够在服务工作或脚本工作的用户代码中抛出 BPMN 谬误。能够在 Java 委托、脚本、表达式与委托表达式中,抛出非凡的 FlowableException:BpmnError。引擎会捕捉这个异样,并将其转发至适合的谬误处理器,如谬误边界事件或谬误事件子流程。

    public class ThrowBpmnErrorDelegate implements JavaDelegate {public void execute(DelegateExecution execution) throws Exception {
        try {executeBusinessLogic();
        } catch (BusinessException e) {throw new BpmnError("BusinessExceptionOccurred");
        }
      }
    }

  构造函数的参数是错误代码。错误代码决定了解决这个谬误的谬误处理器。

  这个机制 只应该用于业务谬误,须要通过流程中定义的谬误边界事件或谬误事件子流程解决。技术谬误应该通过其余异样类型体现,并且通常不在流程外部解决。

1.2.6.2 异样映射

  能够应用 mapException 扩大,间接将 Java 异样映射至业务异样(谬误)。单映射是最简略的模式:

    <serviceTask id="servicetask1" flowable:class="...">
      <extensionElements>
        <flowable:mapException
              errorCode="myErrorCode1">com.example.SomeException</flowable:mapException>
      </extensionElements>
    </serviceTask>

  在下面的代码中,如果服务工作抛出 org.flowable.SomeException 的实例,引擎会捕捉该异样,并将其转换为带有给定 errorCode 的 BPMN 谬误。而后就能够像一般 BPMN 谬误齐全一样地解决。其余的异样没有映射,仍将抛出至 API 调用处。

  也能够在单行中应用 includeChildExceptions 属性,映射特定异样的所有子异样。

    <serviceTask id="servicetask1" flowable:class="...">
      <extensionElements>
        <flowable:mapException errorCode="myErrorCode1"
               includeChildExceptions="true">com.example.SomeException</flowable:mapException>
      </extensionElements>
    </serviceTask>

  下面的代码中,Flowable 会将 SomeException 的任何间接或间接的子类,转换为带有指定错误代码的 BPMN 谬误。当未指定 includeChildExceptions 时,视为“false”。

1.2.6.3 默认映射

  默认映射最罕用。默认映射是一个不指定类的映射,能够匹配任何 Java 异样:

    <serviceTask id="servicetask1" flowable:class="...">
      <extensionElements>
        <flowable:mapException errorCode="myErrorCode1"/>
      </extensionElements>
    </serviceTask>

  除了默认映射,会依照从上至下的程序查看映射,应用第一个匹配的映射。只在所有映射都不能胜利匹配时应用默认映射。只有第一个不指定类的映射会作为默认映射。默认映射疏忽includeChildExceptions

1.2.6.4 异样程序流

  还有种举荐用法,在产生异样时,将流程执行路由至另一条门路。上面是一个例子。

    <serviceTask id="servicetask1" flowable:class="com.example.ThrowsExceptionBehavior">
    </serviceTask>

    <sequenceFlow id="no-exception" sourceRef="javaService" targetRef="theEnd" />
    <sequenceFlow id="exception" sourceRef="javaService" targetRef="fixException" />

  服务工作有两条进口程序流,命名为 exceptionno-exception。在产生异样时,应用程序流 ID 管制流程流向:

    public class ThrowsExceptionBehavior implements ActivityBehavior {public void execute(DelegateExecution execution) {String var = (String) execution.getVariable("var");

        String sequenceFlowToTake = null;
        try {executeLogic(var);
          sequenceFlowToTake = "no-exception";
        } catch (Exception e) {sequenceFlowToTake = "exception";}
        DelegateHelper.leaveDelegate(execution, sequenceFlowToTake);
      }

    }

1.3 脚本工作

1.3.1 形容

  脚本工作(script task)是主动执行的流动。当流程执行达到脚本工作时,会执行相应的脚本。

1.3.2 图示

  脚本工作用左上角有一个小“脚本”图标的规范 BPMN 2.0 工作(圆角矩形)示意。

1.3.3 XML 示意

  脚本工作应用 scriptscriptFormat元素定义。

    <scriptTask id="theScriptTask" scriptFormat="groovy">
      <script>
        sum = 0
        for (i in inputArray) {sum += i}
      </script>
    </scriptTask>

  默认状况下,JavaScript 蕴含在每一个 JDK 中,因而不须要增加任何 JAR 文件。如果想应用其它脚本引擎,则须要在 classpath 中增加相应的 jar,并应用适当的名字。例如,Flowable 单元测试常常应用 Groovy。Groovy 脚本引擎与 groovy-all JAR 捆绑在一起。增加如下依赖:

    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.x.x<version>
    </dependency>

1.3.4 脚本中的变量

  达到脚本引擎的执行中,所有的流程变量都能够在脚本中应用。在这个例子里,脚本变量 ‘inputArray’ 实际上就是一个流程变量(一个 integer 的数组)。

    <script>
        sum = 0
        for (i in inputArray) {sum += i}
    </script>

  在脚本中设置变量的例子:

    <script>
        def scriptVar = "test123"
        execution.setVariable("myVar", scriptVar)
    </script>

留神:下列名字是保留字,不能用于 变量名:out,out:print,lang:import,context,elcontext

1.3.5 脚本工作的后果

  脚本工作的返回值,能够通过为脚本工作定义的 ‘flowable:resultVariable’ 属性设置为流程变量。能够是曾经存在的,或者新的流程变量。如果指定为已存在的流程变量,则流程变量的值会被脚本执行的后果值笼罩。如果不指定后果变量名,则脚本后果值将被疏忽。

    <scriptTask id="theScriptTask" scriptFormat="juel" flowable:resultVariable="myVar">
      <script>#{echo}</script>
    </scriptTask>

  在下面的例子中,脚本执行的后果(解析表达式 ‘#{echo}’ 的值),将在脚本实现后,设置为名为 ‘myVar’ 的流程变量。

1.4 业务规定工作

1.4.1 形容

  在企业应用中,举荐做法是应用可保护的规定库来治理复杂多变的业务规定,将业务代码和规定离开保护,一旦规定有变动,只需批改预设规定即可,而不会影响到业务代码。

  业务规定工作能够依据流程变量的值解决预设的业务规定。Flowable 反对目前最风行的规定引擎——Drools。只需把含有业务规定工作的流程文件和规定引擎文件“.drl”一起打包部署到零碎中,同时增加 Drools 的 jar 包,即可实现 Flowable 驱动规定引擎。

1.4.2 图示

  业务规定工作显示为带有表格图标的圆角矩形。

1.4.3 XML 示意

  要执行业务规定,须要定义输出与后果变量。输出变量能够用流程变量的列表定义,应用逗号分隔。输入变量只能有一个变量名,如果没有指定后果变量名,默认为 org.flowable.engine.rules.OUTPUT。

    <process id="simpleBusinessRuleProcess">
      <startEvent id="theStart" />
      <sequenceFlow sourceRef="theStart" targetRef="businessRuleTask" />

      <businessRuleTask id="businessRuleTask" flowable:ruleVariablesInput="${order}"
          flowable:resultVariable="rulesOutput" />

      <sequenceFlow sourceRef="businessRuleTask" targetRef="theEnd" />

      <endEvent id="theEnd" />
    </process>

  也能够将业务规定工作配置为只执行部署的.drl 文件中的一组规定。要做到这一点,须要指定规定名字的列表,用逗号分隔。

    <businessRuleTask id="businessRuleTask" flowable:ruleVariablesInput="${order}"
          flowable:rules="rule1, rule2" />

  这样只会执行 rule1 与 rule2。

  也能够定义须要从执行中排除的规定列表。

    <businessRuleTask id="businessRuleTask" flowable:ruleVariablesInput="${order}"
          flowable:rules="rule1, rule2" exclude="true" />

  这个例子中,除了 rule1 与 rule2 之外,其它所有与流程定义一起部署的规定都会被执行。

留神:集成 Drools 的业务规定工作,是企业应用中的重要内容,须要重点把握。

1.5 执行监听器

1.5.1 形容

  执行监听器(execution listener)能够在流程执行中产生特定的事件时,执行内部 Java 代码或计算表达式。能够被捕捉的事件有:

  • 流程实例的启动和完结。
  • 流程执行转移。
  • 流动的启动和完结。
  • 网关的启动和完结。
  • 两头事件的启动和完结。
  • 启动事件的完结,和完结事件的启动。

1.5.2 XML 示意

  上面的流程定义蕴含了三个执行监听器:

<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 接口。当该事件产生时(这里是 start 事件),会调用 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 接口的委托类。这些委托类也能够用于其余的构造,如服务工作的委托。

  第二个执行监听器在流程执行转移时被调用。请留神 listener 元素并未定义 event,因为在转移上只会触发take 事件。当监听器定义在转移上时,event属性的值将被疏忽。

最初一个执行监听器在 secondTask 流动完结时被调用。监听器申明中没有应用class,而是定义了expression。这个表达式将在事件触发时计算 / 调用。

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

  与其余表达式一样,能够应用与解析 execution 变量。

1.5.3 执行监听器上的字段注入

  应用通过 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>

  ExampleFieldInjectedExecutionListener类将连贯两个字段(一个是固定值 -fixedValue,另一个是动静值 -dynamicValue),并将其存储在 ’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);

      // 后果为固定注入字段及注入表达式的连贯
      assertEquals("Yes, I am listening!", varSetByListener);
    }

1.6 工作监听器

1.6.1 形容

  工作监听器(task listener)用于在特定的工作相干事件产生时,执行自定义的 Java 逻辑或表达式。

1.6.2 XML 示意

  工作监听器只能在流程定义中作为用户工作的子元素。请留神,工作监听器是一个 Flowable 自定义构造,因而也须要作为 BPMN 2.0 extensionElements,放在flowable 命名空间下。

    <userTask id="myTask" >
      <extensionElements>
        <flowable:taskListener event="create" class="com.example.MyTaskCreateListener" />
      </extensionElements>
    </userTask>

1.6.3 工作监听器属性:

1.6.3.1 event

  触发工作监听器的工作事件类型,必填项。可用的事件有:

  • create(创立):当工作曾经创立,并且 所有工作参数都曾经设置 时触发。
  • assignment(指派):当工作曾经指派给某人时触发。请留神:当流程执行达到用户工作时,在触发 create 事件 之前 ,会首先触发assignment 事件。这程序看起来不太天然,然而有理论起因的:当收到 create 事件时,咱们通常心愿能看到工作的所有参数,包含办理人。
  • complete(实现):当工作曾经实现,从运行时数据中删除前触发。
  • delete(删除):在工作行将被删除前触发。请留神工作由 completeTask 失常实现时也会触发。
1.6.3.2 class

  须要调用的委托类。这个类必须实现 org.flowable.engine.delegate.TaskListener 接口。

    public class MyTaskCreateListener implements TaskListener {public void notify(DelegateTask delegateTask) {// 这里是要实现的业务逻辑}
    }

  也能够应用字段注入,为委托类传递流程变量或执行。请留神委托类的实例在流程部署时创立(与 Flowable 中其它的委托类一样),这意味着该实例会在所有流程实例执行中共享。

1.6.3.3 expression

  指定在事件产生时要执行的表达式(不能与 class 属性一起应用)。能够为被调用的对象传递 DelegateTask 对象与事件名(应用task.eventName)作为参数。

    <flowable:taskListener event="create" expression="${myObject.callMethod(task, task.eventName)}" />
1.6.3.4 delegateExpression

  指定一个可能解析为 TaskListener 接口实现类的对象的表达式。

    <flowable:taskListener event="create" delegateExpression="${myTaskListenerBean}" />

1.7 多实例

1.7.1 形容

  多实例流动(multi-instance activity)是在业务流程中,为特定步骤定义反复的形式。在编程概念中,多实例相似 for each 构造:能够为给定汇合中的每一条目,程序或并行地,执行特定步骤,甚至是整个子流程。

  网关和事件不能设置为多实例。

  依照 BPMN2.0 标准的要求,用于为每个实例创立执行的父执行,会提供下列变量:

  • nrOfInstances:实例总数。
  • nrOfActiveInstances:以后流动的(即未实现的)实例数量。对于程序多实例,这个值总为 1。
  • nrOfCompletedInstances:已实现的实例数量。

  能够调用 execution.getVariable(x) 办法获取这些值。

  另外,每个被创立的执行,都有局部变量(对其余执行不可见,也不存储在流程实例级别):

  • loopCounter:给定实例在for-each 循环中的 index

1.7.2 图示

  如果一个流动是多实例,将通过在该流动底部的三条短线示意。三条竖线代表实例会并行执行,而三条横线代表程序执行。

1.7.3 XML 示意

  要将流动变成多实例,该流动的 XML 元素必须有 multiInstanceLoopCharacteristics 子元素

    <multiInstanceLoopCharacteristics isSequential="false|true">
     ...
    </multiInstanceLoopCharacteristics>

  isSequential属性代表了流动的实例为程序还是并行执行。

  有 4 种不同办法能够配置数量。

1.7.3.1 指定数字

  通过 loopCardinality 子元素,间接指定数字:

    <multiInstanceLoopCharacteristics isSequential="false|true">
      <loopCardinality>5</loopCardinality>
    </multiInstanceLoopCharacteristics>
1.7.3.2 表达式

  应用解析为正整数的表达式:

    <multiInstanceLoopCharacteristics isSequential="false|true">
      <loopCardinality>${nrOfOrders-nrOfCancellations}</loopCardinality>
    </multiInstanceLoopCharacteristics>
1.7.3.3 指定汇合

  另一个定义实例数量的办法,是应用 loopDataInputRef 子元素,指定一个汇合型流程变量的名字。对汇合中的每一项,都会创立一个实例。能够应用 inputDataItem 子元素,将该项设置给该实例的局部变量。在上面的 XML 示例中展现:

    <userTask id="miTasks" name="My Task ${loopCounter}" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="false">
        <loopDataInputRef>assigneeList</loopDataInputRef>
        <inputDataItem name="assignee" />
      </multiInstanceLoopCharacteristics>
    </userTask>

  假如变量 assigneeList 蕴含 [kermit, gonzo, fozzie]。下面的代码会创立三个并行的用户工作。每一个执行都有一个名为assignee 的(部分)流程变量,含有汇合中的一项,并在这个例子中被用于指派用户工作。

  loopDataInputRefinputDataItem 的毛病是名字很难记,并且因为 BPMN 2.0 概要的限度,不能应用表达式。Flowable 通过在 multiInstanceCharacteristics 上提供 collectionelementVariable属性解决了这些问题:

    <userTask id="miTasks" name="My Task" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="true"
         flowable:collection="${myService.resolveUsersForTask()}" flowable:elementVariable="assignee" >
      </multiInstanceLoopCharacteristics>
    </userTask>

  请留神 collection 属性会作为表达式进行解析。如果表达式解析为字符串而不是一个汇合,不论是因为自身配置的就是动态字符串值,还是表达式计算结果为字符串,这个字符串都会被当做变量名,在流程变量中用于获取理论的汇合。

  例如,上面的代码片段会让引擎查找存储在 assigneeList 流程变量中的汇合:

    <userTask id="miTasks" name="My Task" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="true"
         flowable:collection="assigneeList" flowable:elementVariable="assignee" >
      </multiInstanceLoopCharacteristics>
    </userTask>
1.7.3.4 条件型数量

  多实例流动在所有实例都实现时完结。然而,也能够指定一个表达式,在每个实例完结时进行计算。当表达式计算为 true 时,将销毁所有残余的实例,并完结多实例流动,继续执行流程。这个表达式必须通过 completionCondition 子元素定义。

    <userTask id="miTasks" name="My Task" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="false"
         flowable:collection="assigneeList" flowable:elementVariable="assignee" >
        <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </userTask>

  在这个例子里,会为 assigneeList 汇合中的每个元素创立并行实例。当 60% 的工作实现时,其余的工作将被删除,流程持续运行。

二、集成扩大的工作类型

  Flowable 还有很多集成扩大型的工作,这类工作并不罕用,初学读者能够略过,在须要时再回头查阅。

2.1 手动工作

2.1.1 形容

  手动工作(manual task)用来定义在 BPM 引擎不能实现的工作。对于引擎来说,手动工作将当做一个空工作来解决,在流程执行达到手动工作时,主动继续执行流程。

2.1.2 图示

  手动工作用左上角有一个小“手”图标的规范 BPMN 2.0 工作(圆角矩形)示意。

2.1.3 XML 示意

    <manualTask id="myManualTask" name="Call client for more information" />

2.2 Java 接管工作

2.2.1 形容

  接管工作(receive task),是期待特定音讯达到的简略工作。当流程执行达到接管工作时,将放弃期待状态,直到引擎接管到特定的音讯,触发流程穿过接管工作继续执行。

2.2.2 图示

  接管工作用左上角有一个音讯图标的规范 BPMN 2.0 工作(圆角矩形)示意。音讯图标是红色的(对应的彩色音讯图标代表发送的含意)。

2.2.3 XML 示意

    <receiveTask id="waitState" name="wait" />

2.2.4 应用办法

  要使流程实例从接管工作的期待状态中继续执行,须要应用达到接管工作的执行 id,调用runtimeService.signal(executionId)。上面的代码片段展现了如何操作:

    ProcessInstance pi = runtimeService.startProcessInstanceByKey("receiveTask");
    Execution execution = runtimeService.createExecutionQuery()
      .processInstanceId(pi.getId())
      .activityId("waitState")
      .singleResult();

    runtimeService.trigger(execution.getId());

2.3 Shell 工作

2.3.1 形容

  Shell 工作(Shell task)能够运行 Shell 脚本与命令。请留神 Shell 工作 不是BPMN 2.0 标准的“官网”工作(因而也没有专用图标)。

2.3.2 定义 Shell 工作

  Shell 工作实现为非凡的服务工作,将服务工作的 type 定义为 ‘shell’ 进行设置。

    <serviceTask id="shellEcho" flowable:type="shell">

2.3.3 Shell 工作参数

  Shell 工作通过字段注入配置。这些参数的值能够应用 EL 表达式,将在流程执行运行时解析。能够设置下列参数:

参数 必填? 类型 形容 默认值
command String 要执行的 Shell 命令。
arg0-5 String 参数 0 至参数 5
wait true/false 是否期待 Shell 过程终止。 true
redirectError true/false 是否将规范谬误(standard error)并入规范输入(standard output)。 false
cleanEnv true/false 是否防止 Shell 过程继承以后环境。 false
outputVariable String 保留输入的变量名 不会记录输入。
errorCodeVariable String 保留后果错误码的变量名 不会记录错误码。
directory String Shell 过程的默认目录 当前目录

2.3.4 应用示例

  上面的 XML 代码片段是应用 Shell 工作的例子。将会运行 ”cmd /c echo EchoTest” Shell 脚本,期待其完结,并将其后果存入resultVar

    <serviceTask id="shellEcho" flowable:type="shell" >
      <extensionElements>
        <flowable:field name="command" stringValue="cmd" />
        <flowable:field name="arg1" stringValue="/c" />
        <flowable:field name="arg2" stringValue="echo" />
        <flowable:field name="arg3" stringValue="EchoTest" />
        <flowable:field name="wait" stringValue="true" />
        <flowable:field name="outputVariable" stringValue="resultVar" />
      </extensionElements>
    </serviceTask>

2.4 弥补处理器

2.4.1 形容

  如果要应用一个流动弥补另一个流动的影响,能够将其申明为 弥补处理器(compensation handler)。弥补处理器不在失常流程中执行,而只在流程抛出弥补事件时才会执行。

  弥补处理器不得有入口或进口程序流。

  弥补处理器必须通过单向的连贯,关联一个弥补边界事件。

2.4.2 图示

  如果一个流动是弥补处理器,则会在其下部两头显示弥补事件图标。上面摘录的流程图展现了一个带有弥补边界事件的服务工作,并关联至一个弥补处理器。请留神弥补处理器图标显示在 ”cancel hotel reservation(勾销酒店预订)” 服务工作的下部两头。

2.4.3 XML 示意

  要将一个流动申明为弥补处理器,须要将 isForCompensation 属性设置为 true:

    <serviceTask id="undoBookHotel" isForCompensation="true" flowable:class="...">
    </serviceTask>

2.5 集成类工作

  • Web Service 工作:调用内部的 Web Service 资源。
  • 邮件工作:用于发送邮件。
  • Http 工作:用于收回 Http 申请。
  • Camel 工作:集成音讯路由框架 Camel。
  • Mule 工作:集成企业系统总线框架 Mule。

  下面的集成类工作在后续篇章中会具体介绍集成内容,此处理解即可。

三、小结

  本篇介绍了 BPMN2.0 标准下及 Flowable 自定义扩大的工作类型,Flowable 提供的多种工作类型根本笼罩企业应用的需要。但还有不少问题须要咱们关注,比方脚本工作中的脚本平安和多实例中的线程平安。

退出移动版