学习 jBPM 的第一步,是学习它的 workbench。
workbench 是 jBMP 的基于 web 的一系列工具集,也就是你用 ant start.demo 起起来的那个服务器。一旦启动了 workbench,你就可以用 http://localhost:8080/jbpm-console/ 来访问它。
workbench 默认的管理员密码是 admin/admin。登陆后的主界面是这样的:
顶部工具栏分别是:
左上角:
右上角:
主界面中有 4 个图标,从左至右分别是:
一个流程中经常需要不同用户角色的参与。因此我们首先用到的功能的就是用户管理。点击右上角的“设置”图标(齿轮图标),点击 用户->New 用户
,就可以新建用户。
依次新建 4 个用户:zhangsan1、lisi1、wangwu、zhaoliu。
注意,用户的组中必须分配一个 kie-server,角色可以是 user,用户名不能是中文或者 zhangsan、lisi 等常见名称,否则可能无法登录。
创建好用户,点击 Save 保存,你就可以用这个用户登录 workbench 并办理任务。
点击 Menu -> Design -> Projects,进入项目设计界面。默认项目列表是空的,但你可以导入一些官方代码库中的示例,也可以自己新建一个项目。
点击 Add Project,创建项目。输入项目名称 get-started
,点添加,就可以创建一个项目。
刚刚新建的项目,没有 asset,你可以通过 Import Asset 导入 asset,也可以 Add Asset 手动添加 Asset。后者的好处是你可以用 workbench 中提供的流程设计器绘制流程图。workbench 提供的流程设计器比 Eclipse 可是好用多了,所以我们选择 Add Asset。会弹出一个列表,选择 Business Process,绘制流程图。
然后让你输入流程名称,比如 leaveprocess,以及包名:com.myspace.get_started。
这个 id 和 packageName 很关键,后面如果要 import 该 asset 时,文件名必须和 id 匹配。比如 id 叫做 get-started.test,那么文件名只能叫做 test.bpmn。
点击确定,进入流程设计器。
接下来我们绘制一个最常见的请假流程。
新建的流程图默认有一个开始节点,点击这个节点,选择 Create Parallel,创建一个网关。然后选择 Convert into Exclusive,转换成排他性网关(即网关 type 为 XOR)。
图中有一个错误,即图上的网关图标还是并行网关的图标(+ 号),正确的做法是要把它转换成排他性网关( x 号)。
点击 Create Task,创建任务,然后选择 Convert into User,转换成用户任务。
双击这个用户任务,将名称修改为 提交申请
。
点击 Create Task,再次创建一个 User Task,命名为 Leader审批
。
继续绘制剩下流程图。包括:
Leader审批
之后,两个位于 Director审批
之后。 Director审批
和 HR备案
。 为了方便查看,我们也稍微调整了节点的位置,最终效果如下:
在空白地方单击,打开右边的属性面板,点击 Process Variables 下边的 + 按钮,添加如下流程变量:
既然。网关,就不可能只有一个入口和一个出口,接下来为每个网关添加其它出口或入口。
第一个网关
这个网关用来回到 提交申请
节点。之所以要用这个网关,是因为 BPMN 2.0 规定普通节点只能有一个入口和一个出口。因为 提交申请
这个节点有可能会有多个子流程进入这个节点:
提交申请
节点。 Leader审批
时,如果Leader 不同意申请,进行了驳回操作,那么流程也会自动回到 提交申请
节点。 Director审批
时,如果 Director 不同意申请,进行了驳回操作,那么流程也会自动回到 提交申请
节点。
因为 BPMN 2.0 中任务节点只能有一个入口,那么对于这种有多个入口的情况,只能借助于网关实现了。所以第一个网关的作用就是为 提交申请
节点增加多个入口。
第一个入口已经有了,我们需要增加另外 2 个入口。因此需要绘制另外两根线(即Sequence Flow)。
首先从第二个网关( Leader审批
之后的网关)画一根线到第一个网关,并命名为 leader驳回
。
打开属性面板,将分支条件设置为 leaderAgree==false:
再从第三个网关( Director审批
之后的网关)画一根线到第一个网关,命名为 director驳回
。
打开属性面板,将分支条件设置为 directorAgree==false:
第二个网关
这个网关是 leader审批
节点执行后的分支。这个分支有三个出口:
Director审批
节点(已经画出来了,但还没有配置条件表达式)。 HR备案
节点前面的网关(因为 HR备案
节点不能有两个入口,所以借用了一个网关实现)。
第一个出口在前面已经实现。我们来看第二个出口,选中这根线,打开属性面板,设置 name 为 leader同意,days>=3
,然后设置条件表达式为 return KieFunctions.isTrue(leaderAgree&&days>=3);
:
有的条件比较复杂,不再是对单个的流程变量值进行计算,那么我们可以使用表达式来实现。不要怀疑,这个表达式是真正的 java 语句(也可以是其它语言)。
第三个出口还没有画。从第二个网关画一条线到第四个网关(注意,不是第三个),命名为 leader同意,days<3
,然后将条件表达式设为 return KieFunctions.isTrue(leaderAgree&&days<3);
。
第三个网关
这个网关有两个出口,第一条分支 director驳回
已经配置好,只需要配置第二条分支的 Name 属性和条件表达式即可:
第四个网关
这个网关有两个入口,两个入口都在上面的步骤中配置好了,不用再配置。
前面已经设置了流程变量,流程变量是一种全局变量,在整个流程生命周期(无论是哪个节点)都可见。除此之外还有任务变量的概念,即局部变量,任务变量是在 Task 中使用的变量,它们的作用域只在于任务的生命周期,当任务结束,任务变量就销毁。
任务变量用于在执行任务(尤其是 User 任务)时存储任务办理时需要使用到的值,比如搜集用户输入。
以 提交申请
为例。这个任务需要读取一些数据,比如 reason(事由)、date(请假日期)、days(请假天数),这些数据已经声明为流程变量。另外这个任务还会写入一些数据,比如 applicantSubmit(标志申请是否已经提交)。
因此任务变量分成了两种:输入及输出。这些变量的赋值统一放在了属性面板的 Assignment 中进行,并分为了 数据输入及分配
以及 数据输出及分配
两种,分别对应 输入变量
和 输出变量
。
1. 提交申请
节点。点击属性面板中的 Assignments
(赋值)。弹出一个对话框。通过 + 按钮,分别对 输入变量
和 输出变量
进行如下赋值:
点击保存。
_in 后缀表示输入变量,_out 后缀表示输出变量。显然,输入变量主要用于读取全局变量的值,输出变量主要用于向全局变量写入值。
其中 ActorId 变量比较特殊,它表示这个任务将分配给 applicant 变量所表示的用户(也就是设置任务的 assignee)。通过这种方式,我们实现了任务的动态分配。
2. Leader审批
节点。
3. Director审批
节点。
4. HR备案
节点
Menu -> Projects,进入 get-started
的项目页面,点击 Build、Deploy,进行编译和发布。如果出现 冲突
,选择 覆盖
。
Menu -> Manage -> 新建过程实例 。如果流程定义有多个版本,请选择最新版本。
新建成功后,可以看到列表中多出了一个活动的流程实例:
点击流程实例,可以查看到流程实例细节、过程变量、流程图等:
流程实例启动之后,就可以查看待办了。由于开始节点是自动办结的,流程一启动就会自动完成开始节点,因此此时流程已经流转到第二个节点,即 提交申请
环节,从上面的流程实例细节也可以看到,当前实例的 活动用户任务
已经不再是 Start
任务了,而是 提交申请
。而这个任务是分配给 zhangsan1
这个用户的,因此我们需要登录 zhangsan1
这个账号才能查看到这个任务。
退出 admin
,登录 zhangsan1
用户。然后点击 Menu -> Track -> Task Inbox
,查看待办。
点击该任务,可以对该任务进行操作:
这里的 Inputs 和 Outputs 就是我们绘制流程图时设置的任务变量。Workbench 根据输入变量和输出变量自动生成了这个表单。输入变量是只读的,它们只是全局变量赋值过来的,你不能填写,输出变量可以由用户填写——但目前你还不能编辑它们,因为你需要首先 启动
(或者 认领
)任务。
点击 启动
,认领这个任务。同样是之前的那个表单,不同的是现在你可以编辑输出变量了。勾上 ApplicantSubmit_out,点击完成:
注意,这里有一处错误,对于这个任务而言,输出变量其实只要 ApplicantSubmit_out 一个就够了,其余 3 个都是不必要的,你可以将它们删除。
这样 zhangsan1
就完成了这个任务。接下来的任务应该是 Leader审批
环节。
点击 Menu -> Track -> Task Reports,查看任务报告:
可以看到当前所有流程实例(目前只有 1 个)统计出来的任务总数是 2,其中已完成的是 1 个(即 提交申请
),待办的是 1 个(即 Leader审批
)。此外还有以各种方式的统计图表。
分别以 lisi1
、 wangwu
和 zhaoliu
进行登录,完成整个流程,同时查看任务报告中各统计数据的变化。
完成流程之后,可以用 Menu -> Track -> Process Reports 查看流程报告,可以查看流程实例的统计数据:
启动新的流程实例,分别测试其它分支的情况,比如请假天数 < 3 天,leader 驳回和 director 驳回的情况,看流程的流向是否正确。
workbench 设计的流程表单是千篇一律的,并没根据任务的情况做出不同的设计,比如前面提到的,Outputs 中的表单是把所有的输出变量都列出来了,不管这个任务有没有用到。
因此,我们需要手动设计每个任务的表单。
Menu -> Projects,进入项目管理页面,可以看到除了我们绘制的流程图以外, workbench 还自动为我们生成了一个表单(最下面的 Task-taskform):
点击它,进入表单设计器,点击重命名,输入 提交申请-taskform
然后点 rename。
重命名后别忘记点击保存按钮,否则不会生成新的表单。
返回 assets 列表,你会看到 提交申请-taskform
:
点击 提交申请-taskform
,进入表单设计器,将 Outputs 中除了第一项之外的变量删除:
然后点击 编辑
,将 Label 改为提交:
任务表单的命名规则是 {任务名称}-taskform
,比如 提交申请-taskform
,表示这个表单是在执行到用户任务 提交申请
时使用的表单。
同样的方式,我们分别创建出 Leader审批
、 Director表单
、 HR备案
表单。
流程表单就是流程启动时显示给用户的表单。目前我们使用的是表单引擎默认生成的表单:
可以看到默认的流程表单会把所有的全局变量都罗列出来,这是没有必要的。我们需要重新设计流程表单。
进入流程图设计器,点击 Generate process form:
这会在 assets 列表中多出一项 get-started.test-taskform
:
流程表单的命名规范是 {流程ID-taskform}
,比如我们的流程 ID 是 get-started.test
,所以表单名称就是 get-started.test-taskform
。
因为流程表单是在流程启动时显示的,而流程启动一般系统进行的,不是用户任务,不需要用户输入,因此将流程表单中的所有输出参数删除:
Build & Deploy 流程定义,开启新实例,测试流程。可以发现修改后的流程表单:
填写表单,提交。
不要依赖表单中的 placeholder,placeholder 仅仅是一个提示信息,不表示为实例变量提供了默认值。
如果你某些字段没有填写,将导致流程实例无法流转。比如这里的申请人没有填写,那么下一个任务 提交申请
将无法生成。
你可以查看流程实例的 过程变量
来确认是否某些全局变量没有赋值。