Flowable工作流简介(一)

1. 简介

Flowable是一个使用Java编写的轻量级业务流程引擎。Flowable流程引擎可用于部署BPMN 2.0流程定义(用于定义流程的行业XML标准), 创建这些流程定义的流程实例,进行查询,访问运行中或历史的流程实例与相关数据等。Flowable可以十分灵活地加入你的应用/服务/构架。可以将JAR形式发布的Flowable库加入应用或服务,来嵌入引擎。 以JAR形式发布使Flowable可以轻易加入任何Java环境:Java SETomcatJettySpring之类的servlet容器;JBossWebSphere之类的Java EE服务器,等等。

另外,也可以使用Flowable REST API进行HTTP调用。也有许多Flowable应用(Flowable Modeler, Flowable Admin, Flowable IDM Flowable Task),提供了直接可用的UI示例,可以使用流程与任务。

 

2. 系统原理

2.1 创建流程引擎

初始化ProcessEngine流程引擎实例。这是一个线程安全的对象,因此通常只需要在一个应用中初始化一次。 ProcessEngineProcessEngineConfiguration实例创建。该实例可以配置与调整流程引擎的设置。

通常使用一个配置XML文件创建ProcessEngineConfiguration,但是(像在这里做的一样)也可以编程方式创建它。 ProcessEngineConfiguration所需的最小配置,是数据库JDBC连接.

 

2.2 部署流程定义

l 开始事件:图中用细线圆圈来表示,是流程实例的开始点

箭头:表示节点之间的流转指向。

l 用户任务 在图中用左上角有人的圆角矩形表示,这些是需要用户来操作的节点。图中有两个,第一个表示需要经理进行审批来同意或拒绝,第二个表示用户来确认销假。

排它网关 用叉形符号填充的菱形表示,从该图中出来的箭头往往有多个,但只有一个满足条件,流程会沿着满足条件的方向流转。

自动化任务 :左上角有齿轮形状的的圆角矩形,表示自动执行的节点。图中上面的表示请假被经理同意后自动注册通知到外部系统,下面的表示请假被经理拒绝后自动发邮件通知给申请人。

结束事件 图中用粗线圆圈表示,表示流程的结束。图中上面的结束事件表示请假成功结束,下面的表示请假失败结束。

 

 一般来说,这样的流程定义使用可视化建模工具建立,如Flowable Designer(Eclipse)Flowable Web Modeler(Web应用),保存后可得到bpmn20.xml格式文件

每一个步骤(在BPMN 2.0术语中称作活动(activity)都有一个id属性,为其提供一个在XML文件中唯一的标识符。所有的活动都可以设置一个名字,以提高流程图的可读性。

 活动之间通过顺序流(sequence flow)连接,在流程图中是一个有向箭头。在执行流程实例时,执行(execution)会从启动事件沿着顺序流流向下一个活动。

 离开排他网关(带有X的菱形)的顺序流很特别:都以表达式(expression)的形式定义了条件(condition) 。当流程实例的执行到达这个网关时,会计算条件,并使用第一个计算为true的顺序流。这就是排他的含义:只选择一个。当然如果需要不同的路由策略,可以使用其他类型的网关。

 这里用作条件的表达式为${approved},这是${approved == true}的简写。变量’approved’被称作流程变量(process variable)流程变量是持久化的数据,与流程实例存储在一起,并可以在流程实例的生命周期中使用。

在这个例子里,我们需要在特定的地方(当用户任务提交时,或者以Flowable的术语来说,完成(complete)时)设置这个流程变量,因为这不是流程实例启动时就能获取的数据。

 有了流程BPMN 2.0 XML文件,下来需要将它部署(deploy)到引擎中。部署一个流程定义意味着:

 l 流程引擎会将XML文件存储在数据库中,这样可以在需要的时候获取它。

 l 流程定义转换为内部的、可执行的对象模型,这样使用它就可以启动流程实例。

 将流程定义部署至Flowable引擎,需要使用RepositoryService,其可以从ProcessEngine对象获取。使用RepositoryService,可以通过XML文件的路径创建一个新的部署(Deployment),并调用deploy()方法实际执行:

 可以通过API查询验证流程定义已经部署在引擎中。通过RepositoryService创建的ProcessDefinitionQuery对象实现。

 

2.3 启动流程实例

启动流程实例,需要提供一些初始化流程变量。一般来说,可以通过呈现给用户的表单,或者在流程由其他系统自动触发时通过REST API,来获取这些变量。

使用RuntimeService启动一个流程实例。收集的数据作为一个java.util.Map实例传递,其中的键就是之后用于获取变量的标识符。这个流程实例使用key启动。这个key就是BPMN 2.0 XML文件中设置的id属性

在流程实例启动后,会创建一个执行(execution),并将其放在启动事件上。从这里开始,这个执行沿着顺序流移动到审批的用户任务,并执行用户任务行为。这个行为将在数据库中创建一个任务,该任务可以之后使用查询找到。用户任务是一个等待状态(wait state),引擎会停止执行,返回API调用处。

 

 2.4 事务

 Flowable中,数据库事务扮演了关键角色,用于保证数据一致性,并解决并发问题。当调用Flowable API时,默认情况下,所有操作都是同步的,并处于同一个事务下。这意味着,当方法调用返回时,会启动并提交一个事务。 流程启动后,会有一个数据库事务从流程实例启动时持续到下一个等待状态。比如第一个用户任务。当引擎到达这个用户任务时,状态会持久化至数据库,提交事务,并返回API调用处。

 Flowable中,当一个流程实例运行时,总会有一个数据库事务从前一个等待状态持续到下一个等待状态。数据持久化之后,可能在数据库中保存很长时间,甚至几年,直到某个API调用使流程实例继续执行。请注意当流程处在等待状态时,不会消耗任何计算或内存资源,直到下一次APi调用。

 当第一个用户任务完成时,会启动一个数据库事务,从用户任务开始,经过排他网关(自动逻辑),直到第二个用户任务。或通过另一条路径直接到达结束。

  

2.5 查询与完成任务

 在实际的应用中,会为用户及审批者提供用户界面,让他们可以登录并查看任务列表。其中可以看到作为流程变量存储的流程实例数据,并决定如何操作任务。我们通过执行API调用来模拟任务列表,通常这些API都是由UI驱动的服务在后台调用的。我们还没有为用户任务配置办理人。我们想将第一个任务指派给"经理(managers)"组,而第二个用户任务指派给请假申请的提交人。因此需要为第一个任务添加candidateGroups属性:

 <userTask  id="approveTask"

   name="Approve or reject request"

   flowable:candidateGroups="managers"/>

 并如下所示为第二个任务添加assignee属性。请注意我们没有像上面的’managers’一样使用静态值,而是使用一个流程变量动态指派。这个流程变量是在流程实例启动时传递的:

 <userTask  id="holidayApprovedTask"

   name="Holiday approved"

   flowable:assignee="${employee}"/>

 现在就可以完成任务了。在现实中,这通常意味着由用户提交一个表单。表单中的数据作为流程变量传递。我们在完成任务时传递带有’approved’变量(这个名字很重要,因为之后会在顺序流的条件中使用!)的map来模拟

 

2.7 使用历史数据

选择使用Flowable这样的流程引擎的原因之一,是它可以自动存储所有流程实例的审计数据或历史数据。这些数据可以用于创建报告,深入展现组织运行的情况,瓶颈在哪里,等等。

例如,如果希望显示流程实例已经执行的时间,就可以从ProcessEngine获取HistoryService,并创建历史活动(historical activities)的查询。

 

 2.8 JAVA类梳理

ProcessDefinition

 这个最好理解,就是流程的定义,也就相当于规范,每个 ProcessDefinition 都会有一个 id

 l ProcessInstance

 这个就是流程的一个实例。简单来说,ProcessDefinition 相当于是类,而 ProcessInstance 则相当于是根据类 new 出来的对象。

 l Activity

 Activity 是流程标准规范 BPMN2.0 里面的规范,流程中的每一个步骤都是一个 Activity

 l Execution

 Execution 的含义是流程的执行线路,通过 Execution 可以获得当前 ProcessInstance 当前执行到哪个 Activity

 l Task

 Task 就是当前要做的工作。

  

3. 集成SpringBoot

 Flowable使用同一个starter支持Spring Boot 2.01.5。主要支持Spring Boot 2.0。所以监控(actuator) endpoint只支持2.0Flowablestarter直接引用Spring Boot starter,所以如果需要使用1.5版的Spring Boot starter,需要自行定义。

 Spring Boot提倡约定大于配置。要开始工作,只需在项目中添加flowable-spring-boot-starterflowable-spring-boot-starter-rest依赖。如果不需要引入所有的引擎,可以查看其它的Flowable starter。如使用Maven

 <dependency> 

  <groupId>org.flowable</groupId> 

  <artifactId>flowable-spring-boot-starter</artifactId> <version>${flowable.version}</version> 

</dependency>

配置好数据库,编写主程序入口文件,只是在pom中添加依赖,并使用@SpringBootAplication注解,就会在幕后发生很多事情:

自动创建了内存数据库(因为classpath中有H2驱动),并传递给Flowable流程引擎配置

创建并暴露了FlowableProcessEngineCmmnEngineDmnEngineFormEngineContentEngineIdmEngine bean

所有的Flowable服务都暴露为Spring bean

创建了Spring Job Executor

并且:

l processes目录下的任何BPMN 2.0流程定义都会被自动部署。创建processes目录,并在其中创建示例流程定义(命名为one-task-process.bpmn20.xml)。

l cases目录下的任何CMMN 1.1事例都会被自动部署。

l forms目录下的任何Form定义都会被自动部署。

启用REST、配置数据库后,创建一个新的Spring服务类,并创建两个方法:一个用于启动流程,另一个用于获得给定任务办理人的任务列表。在这里只是简单地包装了Flowable调用,但在实际使用场景中会比这复杂得多。

posted @ 2024-05-21 17:07  勇敢-的心  阅读(1602)  评论(0编辑  收藏  举报