2 Star 55 Fork 49

Flowable_BPMN / demo09

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

环境:

jkd8+

mysql5.6+

flowable6.4.0

1、原理

1.1 用户任务

​ 一个用户任务被用来模拟需要由人来完成的工作。当流程执行到达此类用户任务时,将在分配给该任务的任何用户或组的任务列表中创建新任务。

1.2 脚本任务

1.2.1 脚本任务是一种自动活动。当进程执行到达脚本任务时,将执行相应的脚本。

1.2.2 属性:

  • name:任务属性,用于指示任务的名称
  • type:任务属性,其值必须为“script”以指示任务的类型
  • scriptFormat:指示脚本语言的扩展属性(例如,javascript,groovy)
  • script:要执行的脚本,定义为名为“script”的字段元素中的字符串
  • autoStoreVariables:可选的任务属性标志(默认值:false),指示脚本中定义的变量是否将存储在执行上下文中(请参阅下面的注释)
  • resultVariableName:可选的任务属性,当存在时,将在Execution上下文中使用脚本评估结果存储具有指定名称的变量(请参阅下面的注释)

1.2.3 flowable支持三种脚本任务类型:Javascript、groovy、juel。

通过指定脚本scriptFormat来定义脚本任务类型,其中Groovy脚本引擎与groovy-all JAR捆绑在一起,必须引入相关依赖:

<dependency>
		<groupId>org.codehaus.groovy</groupId>
		<artifactId>groovy-all</artifactId>
		<version>2.5.4</version>
		<type>pom</type>
</dependency>

1.2.4 脚本中的变量:

var sum = a+b;
execution.setVariable("sum",sum);

​ 也可以简单地调用execution.setVariable("variableName", variableValue),在脚本中设置流程变量。默认情况下,变量不会自动储存(请注意,在一些早期版本中是会储存的!)。可以将scriptTaskautoStoreVariables参数设置为true,以自动保存任何在脚本中定义的变量(例如上例中的sum)。然而这并不是最佳实践。最佳实践是显式调用execution.setVariable(),因为在JDK近期的一些版本中,某些脚本语言不能自动保存变量。查看这个链接了解更多信息。

<scriptTask id="script" scriptFormat="JavaScript" flowable:autoStoreVariables="false">

​ 此参数的缺省值是false,这意味着如果从脚本任务定义中省略该参数,则所有声明的变量将仅在脚本的持续时间内存在。

1.2.5 脚本任务的结果

​ 脚本任务的返回值,可以通过为脚本任务定义的*'flowable:resultVariable'*属性设置为流程变量。可以是已经存在的,或者新的流程变量。如果指定为已存在的流程变量,则流程变量的值会被脚本执行的结果值覆盖。如果不指定结果变量名,则脚本结果值将被忽略。

<scriptTask id="juel" name="juel脚本服务" scriptFormat="juel" flowable:autoStoreVariables="false" flowable:resultVariable="myVar">
      <script><![CDATA[#{juelvar}]]></script>
</scriptTask>

1.3 服务任务

1.3.1 有四种方法声明如何调用Java逻辑:

  • 指定实现了JavaDelegate或ActivityBehavior的类
  • 调用解析为委托对象(delegation object)的表达式
  • 调用方法表达式(method expression)
  • 对值表达式(value expression)求值

1.3.2 字段注入与线程安全

​ 通常情况下,在服务任务中使用Java委托与字段注入是线程安全的。然而,有些情况下不能保证线程安全。这取决于设置,或Flowable运行的环境。

当使用flowable:class属性时,使用字段注入总是线程安全的(译者注:仍不完全安全,如对于多实例服务任务,使用的是同一个实例)。对于引用了某个类的每一个服务任务,都会实例化新的实例,并且在创建实例时注入一次字段。在不同的任务或流程定义中多次使用同一个类没有问题。

当使用flowable:expression属性时,不能使用字段注入。只能通过方法调用传递变量。总是线程安全的。

当使用flowable:delegateExpression属性时,委托实例的线程安全性,取决于表达式解析的方式。如果该委托表达式在多个任务或流程定义中重复使用,并且表达式总是返回相同的示例,则字段注入不是线程安全的

1.3.3 线程安全最简单的解决方法是:

  • 使用表达式代替直接使用Java委托,并将所需数据通过方法参数传递给委托。
  • 或者,在每次委托表达式解析时,返回委托类的新实例。这意味着这个bean的scope必须是prototype(原型)(例如在委托类上加上@Scope(SCOPE_PROTOTYPE)注解)。

1.3.4 异常处理

  • 抛出业务异常

​ 可以在服务任务或脚本任务的用户代码中抛出BPMN错误。可以在Java委托、脚本、表达式与委托表达式中,抛出特殊的FlowableException:BpmnError。引擎会捕获这个异常,并将其转发至合适的错误处理器,如错误边界事件或错误事件子流程。

默认映射是一个不指定类的映射,可以匹配任何Java异常:

<serviceTask id="exceptiondeal" name="抛出业务异常" flowable:class="com.study.demo.delegate.ThrowingDelegate">
       <extensionElements>
    	  <flowable:mapException errorCode="localError"/>
  	   </extensionElements>
</serviceTask>
  • 发生异常时,将流程执行路由至另一条路径

    ThrowingDelegate将会抛出BussinessException业务异常,errorcode为localError,Flowable会将BussinessException类,转换为带有指定错误代码的BPMN错误,边界错误捕获事件会捕获到此异常,并继续后续操作。

1.4 业务规则任务

​ 业务规则任务(business rule task)用于同步地执行一条或多条规则。Flowable使用名为Drools Expert的Drools规则引擎执行业务规则。目前,业务规则中包含的.drl文件,必须与定义了业务规则服务并执行规则的流程定义一起部署。这意味着流程中使用的所有.drl文件都需要打包在流程BAR文件中,与任务表单等类似。要了解如何为Drools Expert创建业务规则,请访问位于JBoss Drools的Drools文档。

​ 如果想要使用自己的规则任务实现,比如希望通过不同方法使用Drools,或者想使用完全不同的规则引擎,则可以使用BusinessRuleTask的class或expression属性。这样它会与服务任务的行为完全相同。

​ 要执行与流程定义在同一个BAR文件中部署的一条或多条业务规则,需要定义输入与结果变量。输入变量可以用流程变量的列表定义,使用逗号分隔。输出变量只能有一个变量名,将执行业务规则后的输出对象存储至流程变量。请注意结果变量会包含对象的List。如果没有指定结果变量名,默认为org.flowable.engine.rules.OUTPUT。

1.5 邮件任务

​ Flowable让你可以通过自动的邮件服务任务(email task),增强业务流程。可以向一个或多个收信人发送邮件,支持cc,bcc,HTML文本,等等。请注意邮件任务不是BPMN 2.0规范的“官方”任务(所以也没有专用图标)。因此,在Flowable中,邮件任务实现为一种特殊的服务任务。

1.6 Http任务

​ Http任务(Http task)用于发出HTTP请求,增强了Flowable的集成能力。请注意Http任务不是BPMN 2.0规范的“官方”任务(所以也没有专用图标)。因此,在Flowable中,Http任务实现为一种特殊的服务任务。

1.7 Camel任务

1.7.1 Camel任务

​ Camel任务(Camel task)可以向Camel发送消息,增强Flowable的集成特性。请注意Camel任务不是BPMN 2.0规范的“官方”任务(所以也没有专用图标)。因此,在Flowable中,Camel任务实现为一种特殊的服务任务。还请注意,需要在项目中包含Flowable Camel模块才能使用Camel任务。

1.7.2 连通性测试示例

将试着从Camel接收与发送消息。我们将发送一个字符串,Camel在其上附加一些文字并返回作为结果。发送部分比较普通,即以变量的格式将信息发送给Camel服务。

1.8 手动任务

​ 手动任务(manual task)定义在BPM引擎之外的任务。它用于建模引擎不需要了解,也不需要提供系统或用户界面的工作。对于引擎来说,手动任务将按直接穿过活动处理,在流程执行到达手动任务时,自动继续执行流程。

1.9 Java接收任务

​ 接收任务(receive task),是等待特定消息到达的简单任务。目前,我们只为这个任务实现了Java语义。当流程执行到达接收任务时,流程状态将提交至持久化存储。这意味着流程将保持等待状态,直到引擎接收到特定的消息,触发流程穿过接收任务继续执行。

​ 要使流程实例从接收任务的等待状态中继续执行,需要使用到达接收任务的执行id,调用runtimeService.signal(executionId)

1.10 Shell任务

​ Shell任务(Shell task)可以运行Shell脚本与命令。

​ 将会运行"cat /etc/passwd | grep root" Shell脚本,等待其结束,并将其结果存入resultVar

1.11 执行监听器

​ 执行监听器(execution listener)可以在流程执行中发生特定的事件时,执行外部Java代码或计算表达式。可以被捕获的事件有:

  • 流程实例的启动和结束。
  • 流程执行转移。
  • 活动的启动和结束。
  • 网关的启动和结束。
  • 中间事件的启动和结束。
  • 启动事件的结束,和结束事件的启动。

1.12 任务监听器

​ 任务监听器(task listener)用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式。

任务监听器只能在流程定义中作为用户任务的子元素。请注意,任务监听器是一个Flowable自定义结构,因此也需要作为BPMN 2.0 extensionElements,放在flowable命名空间下。

任务监听器包含下列属性:

  • event(事件)

    (必填):触发任务监听器的任务事件类型。可用的事件有:

    • create(创建):当任务已经创建,并且所有任务参数都已经设置时触发。
    • assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,在触发create事件之前,会首先触发assignment事件。这顺序看起来不太自然,但是有实际原因的:当收到create事件时,我们通常希望能看到任务的所有参数,包括办理人。
    • complete(完成):当任务已经完成,从运行时数据中删除前触发。
    • delete(删除):在任务即将被删除前触发。请注意任务由completeTask正常完成时也会触发。
  • class:需要调用的委托类。这个类必须实现org.flowable.engine.delegate.TaskListener接口。

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

  • delegateExpression:指定一个能够解析为TaskListener接口实现类的对象的表达式。与服务任务类似

  • 较早之前,我们也引入了新的执行监听器类型,org.flowable.engine.impl.bpmn.listener.ScriptTaskListener。这个脚本任务监听器可以为一个任务监听器事件执行一段脚本代码。

    <flowable:taskListener event="complete" class="org.flowable.engine.impl.bpmn.listener.ScriptTaskListener" >
      <flowable:field name="script">
        <flowable:string>
          def bar = "BAR";  // local variable
          foo = "FOO"; // pushes variable to execution context
          task.setOwner("kermit"); // test access to task instance
          bar // implicit return value
        </flowable:string>
      </flowable:field>
      <flowable:field name="language" stringValue="groovy" />
      <flowable:field name="resultVariable" stringValue="myVar" />
    </flowable:taskListener>

1.13 多实例

​ 实例活动(multi-instance activity)是在业务流程中,为特定步骤定义重复的方式。在编程概念中,多实例类似for each结构:可以为给定集合中的每一条目,顺序或并行地,执行特定步骤,甚至是整个子流程。

多实例是一个普通活动,加上定义(被称作“多实例特性的”)额外参数,会使得活动在运行时被多次执行。下列活动可以成为多实例活动:

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

按照BPMN2.0规范的要求,用于为每个实例创建执行的父执行,会提供下列变量:

  • nrOfInstances:实例总数。
  • nrOfActiveInstances:当前活动的(即未完成的),实例数量。对于顺序多实例,这个值总为1。
  • nrOfCompletedInstances:已完成的实例数量。

可以调用execution.getVariable(x)方法获取这些值。

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

  • loopCounter:给定实例在for-each循环中的index。可以通过Flowable的elementIndexVariable属性为loopCounter变量重命名。

1.14 补偿处理器

​ 如果要使用一个活动补偿另一个活动的影响,可以将其声明为补偿处理器(compensation handler)。补偿处理器不在正常流程中执行,而只在流程抛出补偿事件时才会执行。

​ 补偿处理器不得有入口或出口顺序流。

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

​ 中间补偿事件抛出补偿事件给对应的(activityRef指定的节点)节点的补偿处理程序处理。

2、流程图

  • 用户任务

  • 脚本任务

  • 服务任务

  • 服务任务异常处理

  • 业务规则任务

  • 邮件任务

  • Http任务

  • Camel任务

  • 手动任务

  • Java接收任务

  • Shell任务

  • 执行监听器

  • 任务监听器

  • 多实例

  • 补偿处理器

3、配置

3.1 用户任务

fakeLdapService必须是spring 中的bean

<userTask id="usertask" name="用户任务"  flowable:assignee="${fakeLdapService.findManagerForEmployee(emp)}">
</userTask>

Groovy脚本引擎与groovy-all JAR捆绑在一起,必须引入相关依赖:

<dependency>
		<groupId>org.codehaus.groovy</groupId>
		<artifactId>groovy-all</artifactId>
		<version>2.5.4</version>
		<type>pom</type>
</dependency>

3.2 脚本任务

3.3 服务任务

  • spring bean配置详见flowable-context.xml:
<bean id="delegateExpressionBean" class="com.study.demo.delegate.DelegateExpressionBean"/>
 	<bean id="printer" class="com.study.demo.delegate.Printer" />
 	<bean id="split" class="com.study.demo.delegate.Split" />
 	<bean id="genderBean" class="com.study.demo.delegate.Gender"/>
 	<bean id="singletonDelegateExpressionBean" class="com.study.demo.delegate.SingletonDelegateExpressionBean" scope="singleton"/>
 	<bean id="prototypeDelegateExpressionBean" class="com.study.demo.delegate.PrototypeDelegateExpressionBean" scope="prototype"/>
  • 发生异常时,将流程执行路由至另一条路径:
<serviceTask id="exceptiondeal" name="异常处理" flowable:class="com.study.demo.exception.ThrowsExceptionBehavior"></serviceTask>
    <sequenceFlow id="sid-748CA641-57F3-46F8-8D1F-1C409A509F83" sourceRef="serviceTask4" targetRef="exceptiondeal"></sequenceFlow>
    <sequenceFlow id="exception" name="exception" sourceRef="exceptiondeal" targetRef="user"></sequenceFlow>
    <sequenceFlow id="no-exception" name="no-exception" sourceRef="exceptiondeal" targetRef="sid-FB3C07EC-B784-4C3D-BC1B-294C5155FBF0"></sequenceFlow>
public class ThrowsExceptionBehavior implements ActivityBehavior {
	private static final long serialVersionUID = 1L;

	public void execute(DelegateExecution execution) {
		System.out.println("====发生异常时,将流程执行路由至另一条出线继续执行==");
		String var = (String) execution.getVariable("exception");

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

	protected void executeLogic(String value) {
		if (value.equals("throw-exception")) {
			throw new RuntimeException();
		}
	}
}

3.4 业务规则任务

<businessRuleTask id="businessruletask" name="业务规则任务" flowable:ruleVariablesInput="${order}" flowable:resultVariable="rulesOutput"
    					flowable:class="com.study.demo.delegate.MyRuleServiceDelegate"></businessRuleTask>

3.5 邮件任务

  • flowable.cfg.xml配置文件中设置:
<!--邮件服务配置  -->
<property name="mailServerHost" value="smtp.qq.com" />
<property name="mailServerPort" value="587"/>
<property name="mailServerDefaultFrom" value="465243573@qq.com" />
<property name="mailServerUsername" value="465243573@qq.com" />
<property name="mailServerPassword" value="POP3/SMTP服务的授权码(qq邮箱-->设置-->账户-->开启服务-->POP3/SMTP服务-->开启)" />  
<property name="mailServerUseSSL" value="true" />

3.6 Http任务

3.6.1 添加flowable-http依赖

Http任务的默认行为类是org.flowable.http.impl.HttpActivityBehaviorImpl,此类在flowable-http中。

<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-http</artifactId>
    <version>6.4.0</version>
</dependency>

3.6.2 创建自定义Http任务行为类

​ 也可以使用自定义的实现,覆盖Http任务的默认行为。 需要扩展org.flowable.http.HttpActivityBehavior,并覆盖perform()方法。

详见源码DefaultActivityBehaviorFactory中createHttpActivityBehavior方法解析field name为httpActivityBehaviorClass,并利用反射实例化此类。

<serviceTask id="httpGet" flowable:type="http">
  <extensionElements>
    <flowable:field name="httpActivityBehaviorClass">
        <flowable:string>
          <![CDATA[org.example.flowable.HttpActivityBehaviorCustomImpl]]>
        </flowable:string>
    </flowable:field>
  </extensionElements>
</sericeTask>	

3.6.2 配置Http客户端

<bean id="processEngineConfiguration" class="org.flowable.spring.SpringProcessEngineConfiguration">
...
	<!--http任务配置  -->
	<property name="httpClientConfig" ref="httpClientConfig" />
<bean id="httpClientConfig" class="org.flowable.engine.cfg.HttpClientConfig">
    <property name="connectTimeout" value="5000"/>
    <property name="socketTimeout" value="5000"/>
    <property name="connectionRequestTimeout" value="5000"/>
    <property name="requestRetryLimit" value="5"/>
</bean>

3.7 Camel任务

3.7.1 camelContext配置

详见generic-camel-flowable-context.xml文件

<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring" >
	    <packageScan>
	    	<package>com.study.demo.camel</package>
	  	</packageScan>
</camelContext>

3.7.2 引入camel依赖包

<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-camel</artifactId>
    <version>6.4.0</version>
</dependency>

3.7.3 路由及Endpoint 配置

字符串"world"会在结尾连接上名为“input”的参数,并存储在camelBody变量中;

public class SimpleCamelCallRoute extends RouteBuilder{

	@Override
	public void configure() throws Exception {
		from("flowable:camelprocess:simpleCall").transform().simple("${property.input} World");
		
	}

}

3.8 手动任务

3.9 Java接收任务

3.10 Shell任务

3.11 执行监听器

3.12 任务执行器

3.13 多实例

  • 多实例配置及完成条件动态指定:
<userTask id="user" name="多实例">
      <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
        <completionCondition>${mulitiInstance.completeTask(execution)}</completionCondition>
      </multiInstanceLoopCharacteristics>
</userTask>
public class MulitiInstanceCompleteCondition {
	public boolean completeTask(DelegateExecution execution) {
		FlowElement flowElement = execution.getCurrentFlowElement();
		System.out.println("总的任务数量:" + execution.getVariable("nrOfInstances") + "当前获取的任务数量:"
				+ execution.getVariable("nrOfActiveInstances") + " - " + "已经完成的会签任务数量:"
				+ execution.getVariable("nrOfCompletedInstances"));

		System.out.println("=======【当前节点:】========" + flowElement.getName());
		// isComplete为true,直接完成
		String isComplete = execution.getVariable("isComplete").toString();
		
		if ("true".equals(isComplete)) {
			return true;
		}
		return false;
	}
}

3.13.1 流程定义包含了六个执行监听器:

  • 流程启动的时候执行监听器,实现接口ExecutionListener:

    public class ExampleExecutionListenerOne implements ExecutionListener {
    
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    
    	public void notify(DelegateExecution execution) {
            System.out.println("=========================执行器,流程启动时执行=========================");
    		execution.setVariable("variableSetInExecutionListener", "firstValue");
    		execution.setVariable("eventNameReceived", execution.getEventName());
    		execution.setVariable("businessKeyInExecution", execution.getProcessInstanceBusinessKey());
    
    	}
    
    }
  • 第一个人工任务节点,开始的时候执行监听器,实现接口ExecutionListener:

    public class ExampleExecutionListenerTwo implements ExecutionListener {
    
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    
    	public void notify(DelegateExecution execution) {
    		FlowElement currentFlowElement = DelegateHelper.getFlowElement(execution);
            System.out.println("========================【执行器,当前节点】:" + currentFlowElement.getName()+ "=========================");
            
    		execution.setVariable("variableSetInExecutionListener", "secondValue");
            execution.setVariable("eventNameReceived", execution.getEventName());
            
    	}
    
    }
  • 第二个人工任务节点,结束的时候执行监听器,表达式类型:${myExpression.getEventName(execution.eventName)}

    public class MyExpressionExecutionListener {
    
    
    	public String  getEventName(String name) {
    		
    		System.out.println("====================表达式执行监听器,eventName:" + name+"========================");
    		return "expression:" + name ;
    	}
    
    }
  • 第三个人工任务节点,开始的时候执行监听器,委托表达式类型(实现JavaDelegate):${myDelegateExpression}

    public class MyDelegateExpression implements JavaDelegate {
    
    	public void execute(DelegateExecution execution) {
    		FlowElement currentFlowElement = DelegateHelper.getFlowElement(execution);
            System.out.println("=========================【执行器,当前节点】:" + currentFlowElement.getName() + "=========================");
    
    	}
    
    }
  • 第四个人工任务节点,开始的时候执行监听器,脚本类型:ScriptExecutionListener

  • 第五个人工任务节点,开始的时候执行监听器,实现接口ExecutionListener:ExampleFieldInjectedExecutionListener

    public class ExampleFieldInjectedExecutionListener implements ExecutionListener {
    
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    
    	private Expression fixedValue;
    	private Expression dynamicValue;
    	public void notify(DelegateExecution execution) {
    		FlowElement currentFlowElement = DelegateHelper.getFlowElement(execution);
            System.out.println("=========================【执行器,当前节点】:" + currentFlowElement.getName() + "=========================");
    		execution.setVariable("dynamicValue", fixedValue.getValue(execution).toString() +
    		dynamicValue.getValue(execution).toString());
    	}
    
    }

3.14 补偿处理器

3.14.1 补偿处理器配置:

​ 要将一个活动声明为补偿处理器,需要将isForCompensation属性设置为true:

<serviceTask id="compensationHandler" name="补偿处理程序" isForCompensation="true" 	flowable:class="com.study.demo.compensation.CompensationProcessorJavaDelegate"></serviceTask>

3.14.2 中间补偿事件配置:

​ 中间补偿事件抛出补偿事件给对应的(activityRef指定的节点)节点的补偿处理程序处理

<intermediateThrowEvent id="intermediateCompensation" name="中间补偿事件">
	<compensateEventDefinition activityRef="servicetask1" />
</intermediateThrowEvent>

4、测试

4.1 用户任务--UserTaskTest

  • 运行demo
  • 查看数据库表
 SELECT * FROM flowable.ACT_RU_EXECUTION;
 SELECT * FROM flowable.ACT_RU_TASK;
 SELECT * FROM flowable.ACT_RU_VARIABLE;

4.2 脚本任务--ScriptTaskTest

  • 运行demo
  • 查看数据库表
SELECT * FROM flowable.ACT_RU_EXECUTION;
SELECT * FROM flowable.ACT_RU_TASK;

4.3 服务任务

​4.3.1 测试类 ServiceTaskTest

  • 线程安全:

​ 在运行上面流程定义的流程实例后,INSTANCE_COUNT的值为2。这是因为每次解析*${prototypeDelegateExpressionBean}时,都会创建新实例。可以看到三个Expression*成员字段的注入没有任何问题。

​ 在对于单例bean,INSTANCE_COUNT总是1。在这个委托中,没有Expression成员字段(使用MIXED模式)。而在COMPATIBILITY模式下,就会抛出异常,因为需要有成员字段。这个bean也可以使用DISABLED模式,但会禁用上面进行了字段注入的原型bean。

​ 单例bean是线程不安全的。

  • 发生异常时,将流程执行路由至另一条路径
<serviceTask id="exceptiondeal" name="异常处理" flowable:class="com.study.demo.exception.ThrowsExceptionBehavior"></serviceTask>
    <sequenceFlow id="sid-748CA641-57F3-46F8-8D1F-1C409A509F83" sourceRef="serviceTask4" targetRef="exceptiondeal"></sequenceFlow>
    <sequenceFlow id="exception" name="exception" sourceRef="exceptiondeal" targetRef="user"></sequenceFlow>
    <sequenceFlow id="no-exception" name="no-exception" sourceRef="exceptiondeal" targetRef="sid-FB3C07EC-B784-4C3D-BC1B-294C5155FBF0"></sequenceFlow>

4.3.2 测试类 ExceptionForServiceTaskTest

  • 服务任务异常处理

    ​ ThrowingDelegate将会抛出BussinessException业务异常,errorcode为localError,Flowable会将BussinessException类,转换为带有指定错误代码的BPMN错误,监听在此错误上的边界错误捕获事件会捕获到此异常,并继续后续操作。

4.4 业务规则任务--BusinessRuleTaskTest

  • 运行demo

  • 查看数据库表

4.5 邮件任务--MailTaskTest

  • 运行demo
  • 查看数据库表

4.6 Http任务--HttpTaskTest

  • 运行demo
  • 查看数据库表

4.7 Camel任务--CamelTaskTest

  • CamelTaskTest测试类说明

    在这个例子里,将试着从Camel接收与发送消息。我们将发送一个字符串,Camel在其上附加一些文字并返回作为结果。发送部分比较普通,即以变量的格式将信息发送给Camel服务。这是我们的调用代码:

	/**
	 * 启动流程实例并测试连通性
	 * 
	 */
	@Test
	public void testPingPong() {
        Map<String, Object> variables = new HashMap<String, Object>();

        variables.put("input", "Hello");
        Map<String, String> outputMap = new HashMap<String, String>();
        variables.put("outputMap", outputMap);

        runtimeService.startProcessInstanceByKey("camelprocess", variables);
        System.out.println("==============outputMap: " + outputMap);
    }

​ “input”变量是实际上是Camel路由的输入,而outputMap用于捕获Camel传回的结果。

​ 请注意SaveOutput服务任务会从上下文中取出“Output”变量,并存储至上面提到的OutputMap。现在需要 了解变量如何发送至Camel,以及如何返回。这就需要了解Camel行为(Behavior)的概念。变量与Camel通信的方式可以通过CamelBehavior配置。在这个例子里使用默认配置。

  • 查看数据库表
SELECT * FROM flowable.act_ru_task;
SELECT * FROM flowable.act_ru_variable;

4.8 手动任务--ManualTaskTest

  • 运行demo
  • 查看数据库表

4.9 Java接收任务--ReceiveTaskTest

  • 运行demo
  • 查看数据库表

4.10 Shell任务--ShellTaskTest

​ 将会运行"cat /etc/passwd | grep root" Shell脚本,等待其结束,并将其结果存入resultVar

  • 运行demo
  • 查看数据库表

4.11 执行监听器--ExecutionListenerTest

  • 运行demo
  • 查看数据库表

4.12 任务监听器--TaskListenerTest

  • 运行demo
  • 查看数据库表

4.13 多实例--MultilInstanceTest

  • 运行demo
  • 查看数据库表

4.14 补偿处理器--CompensationHandlerTest

  • 运行demo
  • 查看数据库表

空文件

简介

任务: 1、人工任务 2、脚本任务 3、Java服务任务 4、Web服务任务 5、业务规则任务 6、邮件任务 7、Http任务 8、Mule任务 9、Camel任务 10、手动任务 11、Java接收任务 12、Shell任务 13、执行监听器 14、任务监听器 15、多实例(for each) 16、补偿处理器 展开 收起
Java
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/Flowable_BPMN/demo09.git
git@gitee.com:Flowable_BPMN/demo09.git
Flowable_BPMN
demo09
demo09
master

搜索帮助