jBPM5 - 快速指南
jBPM5 - 概述
JBPM 代表"Java 业务流程管理"。它是 JBoss 产品,是一种开源框架。在进一步讨论之前,让我们先定义一个业务流程。
什么是业务流程?
根据定义,业务流程是一系列以可重复顺序进行的任务,由人和/或系统执行以实现业务目标。它描述了需要执行一系列步骤的顺序(使用流程图)。业务流程可以显著提高业务逻辑的可见性和灵活性。
让我们举个例子。以下屏幕截图描绘了大多数 IT 专业人员都能理解的工作流/流程图。这是大多数组织遵循的常见流程,根据员工绩效对其进行评估。

该流程按以下顺序进行 −
员工自我评估并将报告提交给他们的项目经理。
然后,项目经理和人力资源经理会评估您的绩效。根据评估结果,他们会给员工评分。
然后,最终评级或绩效反馈会传达给员工。
此流程适用于几乎所有员工,因此,它是了解业务流程的一个很好的例子。它是一系列任务,并且按特定顺序发生。
什么是 jBPM?
业务流程是理解任何组织框架的关键概念。像 jBPM 这样的技术有助于以高效的方式管理复杂的业务流程。JBPM 是一种可以有效协调业务流程的工具。通常,每个企业级应用程序都会有一系列按特定顺序执行的任务,这些流程可以借助 jBPM 进行协调。
jBPM 的优点在于它类似于流程图。业务分析师也可以轻松理解它。jBPM 可以嵌入到 Java 应用程序中并作为服务运行。
JBPM 的功能
jBPM 是一个用 Java 编写的轻量级、开源、完全可嵌入的流程引擎。其最显著的功能列于下方 −
jBPM 执行使用 BPMN 2.0 规范设计的业务流程。
jBPM 可以与 Eclipse 和类似的 IDE 完全集成,以提供拖放支持来创建工作流。
jBPM 具有可用的 UI 工具,可从设计阶段开始让业务分析师和用户参与进来。
jBPM 在 JPA 和 JTA 的帮助下支持持久性和事务管理。
可以定义自定义工作项处理程序来创建用户定义的任务,该任务稍后可用作其他工作流的组件。
jBPM5 - Eclipse 插件
以下是安装 jBPM 插件的先决条件 −
- Java 1.5(或更高版本)SE JDK
- Eclipse 4.2 或任何版本和 jBPM 插件
由于 jBPM 是用 Java 编写的,我们将在本节中介绍如何添加所需的插件。考虑到大多数 Java 用户使用 Eclipse,让我们看看如何在 Eclipse 中添加 jBPM 插件。
从以下链接下载二进制文件 − http://download.jboss.org/drools/release/5.3.0.Final/
看到这里的 Drools 时不要感到困惑。jBPM 使用相同的插件。如果您已经安装了 Drools 插件,则可以跳过安装步骤。

将其解压到您的硬盘上。然后,启动 Eclipse 并转到帮助 →安装新软件。

单击添加存储库 −

单击本地按钮,然后选择".../binaries/org.drools.updatesite"(您在计算机上下载的位置)

选择Drools 和 jBPM,然后单击下一步按钮。

再次单击下一步并选择"我接受许可协议条款",然后单击完成。软件安装开始 −

安装成功后,您将看到以下对话框 −

单击是。Eclipse 重新启动。现在,转到Windows → 首选项 → Drools → Drools Flow 节点

如果您能够看到如上图所示的节点,则证明插件已成功安装。现在我们准备编写第一个 jBPM 程序了。
jBPM5 - Hello World!
在本章中,我们将使用 jBPM 编写我们的第一个程序"Hello World"。请按照以下步骤操作 −
转到文件 → 新建 → Drools 项目 −

单击下一步。为第一个项目指定一个合适的名称:在本例中为"HelloWorld"。

单击下一步。选中底部的两个复选框,即 −
- 向此项目添加一个示例 HelloWorld 流程文件
- 添加一个用于加载和执行 HelloWorld 流程的示例类

单击 Next。单击 Configure Workspace Settings(以下屏幕截图中标记为红色)−

单击 Add 按钮 −

单击 Add 按钮后,将出现以下屏幕。单击"创建新的 Drools5 运行时"

提供下载 droolsjbpm-tools-distribution-5.3.0.Final.zip
然后,选择已安装的 Drools 运行时并单击确定。

出现以下屏幕。单击完成按钮。

现在,在 Eclipse 中打开 Package Explorer 视图。您将看到以下屏幕 −

ProcessTest.java 类是用于加载规则流 (rf) 文件的类,ruleflow.rf 是为 HelloWorld 项目创建的基本规则流。
双击 ruleflow.rf 文件,您将看到以下规则流 −

绿色 圆圈表示工作流的开始,而 红色 圆圈表示工作流的结束。
左侧面板列出了工作流中使用的不同组件。除了 START 和 END 之外,还有许多组件可用于工作流,我们将在下一节中介绍它们。
START 和 END 事件之间的 Hello 是一个脚本任务,该脚本任务的名称是 Hello。要查看脚本任务"Hello"中编写的代码,请转到 Windows → 显示视图 → 其他 → 属性。

注意 − 在使用 jBPM 时,请始终保持属性视图打开,因为所有配置仅在属性视图中可见。
单击 确定 按钮。现在,选择 Hello,您可以看到"Hello"事件的属性 −

要查看"Hello"事件中编写的完整代码,请选择 Action 属性。

红色标记的圆圈是操作属性的编辑。单击编辑 −

您可以编辑它并编写要在"Hello"脚本任务中执行的代码。让我们编辑它 −

单击OK。现在打开 ProcessTest.java 类并将其作为 Java 应用程序运行。下面给出的是其输出 −

ProcessTest.java 类中使用的术语与 Drools 中使用的术语相同。ProcessTest.java 类中需要注意的一点是 −
ksession.startProcess("com.sample.ruleflow");
当你编写启动流程的代码时,传递给startProcess方法的字符串就是我们打开工作流时的id属性。

jBPM5 - 组件
BPMS 核心是 BPM 的核心。下图描述了 BPMS 核心及其组件。

语义模块
语义模块定义语言语义(每个单词的含义)以及如何将其转换为流程引擎内部结构以准备执行。该模块基本上包含理解 BPMN2 语言的基本知识。
流程引擎
流程引擎负责实际执行我们的业务流程。流程引擎负责创建新的流程实例并保存每个实例的状态。在流程引擎代码中,内部结构被定义为表示流程定义中的每个活动。所有用于实例化这些流程定义的机制都将按照流程引擎中的定义执行它们。
持久性和事务
在大多数企业应用程序中,所有交互都必须在事务边界内运行,并且我们必须处理不同的系统、API 和设计。此外,我们必须有一个灵活的机制来定义 −
如何处理长时间运行的流程
我们如何以及何时存储有关流程状态的信息以及流程正在处理的信息
我们如何以及何时需要创建、提交或回滚流程引擎事务
哪些业务异常可以回滚或补偿已经执行的业务操作
jBPM 中的持久性和事务组件涵盖了上述所有要点。
审计/历史记录
此模块负责为用户提供一种查询流程执行方式的方法。这些信息包括已结束流程的历史信息和正在执行的流程的最新信息。
业务活动监控 (BAM) 工具和信息仪表板是此模块生成的信息的一些最常见客户端。审计/历史记录模块通常用于提取有用的信息和指标,这些信息和指标将与旨在相应地显示此信息的不同工具协作。
jBPM5 - 工作流组件
以下屏幕截图显示了 jBPM 5 中可用的各种工作流组件。使用这些组件,您可以创建工作流来协调您的流程。

您也可以创建自定义任务,但稍后会介绍。此外,还有可用于协调流程的服务任务。
Start 开始事件 − 这是每个流程中执行的第一个节点。您的流程中只能有一个开始节点。
End 结束事件 − 此节点表示流程结束。一个流程中可以出现多个此类节点。
Rule Task(规则任务) − 它是一个评估 RuleFlow 组的节点,该组是同一命名范围下的一组 Drools 规则。
Gateway 网关(发散)又名拆分 − 此特定节点在流程中创建新的路径/方式。它有两个或更多传出连接。您可以在三种不同类型的拆分/门之间进行选择。
AND GATE(与门) − 流程流同时继续流向所有传出连接。
XOR GATE(异或门) − 根据工作流中定义的一些预定义约束,它只转到一条传出路径。
OR GATE(或门) −流程基于对所有传出约束的评估进行,并且当约束评估为真时启用该路径。
网关(汇聚)又名连接 − 此连接是拆分的反向操作。它将多条路径合并为一条。可以有四种不同类型的连接/门 −
AND − 当所有分支都完成时,流程将继续。
XOR − 当至少一个分支完成时,流程将继续。
Discriminator(鉴别器) − 与 XOR 一样,如果其中一个分支已完成,它将继续。但与 XOR 不同的是,它会记录其他分支的完成情况,直到所有连接都已完成。发生这种情况时,节点会重置,当传入分支激活时可以再次进入,然后循环重新开始。
N-of-M − 当 n 个 m 个分支完成时,流程将继续。您需要在配置门时指定 n(数字),以确定在流程退出之前应完成多少个分支。
可重复使用的子流程 − 调用另一个流程。这对于将几个较小的流程组合成一个较大的流程非常有用。这个较大的流程可以是一个协调流程。您可以配置调用流程以等待被调用方完成,并使其具有其父级的独立生命周期。
脚本任务 − 可以执行一段简单代码的节点。
计时器事件 − 这种类型的节点启动计时器并在计时器到期时触发。启用与时间相关的流程和重复性任务。
错误事件 −这种节点表示流程中的错误情况。它没有传出连接。它指定一个 FaultName 和一个 FaultVariable。引擎将搜索与 FaultName 匹配的异常处理程序,并将 Fault 信息存储在由 FaultVariable 定义的变量中。
消息事件 − 当发出预定义类型的事件时触发。它可以是内部事件(在流程内部发出信号)或外部事件(由流程引擎以外的外部实体发出信号)。
用户任务 − 创建人工任务的节点。此人工任务是必须由人类参与者完成的活动。
嵌入式子流程 − 帮助在父流程中创建子流程。它可以有自己的范围。这对于较大的流程非常有用,因为您希望将一些复杂的分支保持隔离。它可以有自己的变量和异常处理程序
多个实例,又称 for Each − 它允许将元素集合输入到子流程中。与可重用子流程结合使用以组成和协调较小的流程时非常有用。
jBPM5 - 绘制并验证工作流
要绘制工作流,您可以使用上述文章中所述的面板中可用的任何组件。所有工作流都有一个开始,但可以有多个结束。
借助屏幕截图,我将向您描述如何创建工作流。
在这里,我打开了空白的 rf 或 bpmn 文件

要添加任何事件,请从组件面板中选择特定事件,然后将其拖放到右侧。例如,我选择了开始事件并将其拖到右侧,还有一个分流网关。

现在,需要连接两个组件。选择序列流并连接两个组件。


这样,您可以将组件拖到编辑器中,并使用序列流连接不同的组件。只需注意某些组件只有一个传入连接和一个传出连接,并需要相应地设置序列流以创建有意义的流。
在绘制工作流时,还需要设置一些属性。将在此处发布所有要设置的属性。我刚刚创建了一个流程,但乍一看它意义不大,因为我没有在创建的工作流中设置任何属性。

如上所示,这是一个空白的工作流,没有任何描述,无法从创建的工作流中看出任何东西。
但是,进一步解释一下,我有一个启动组件,然后是一个分流网关,根据分流网关的条件,我将选择一种方式并在脚本任务中执行一些代码,然后结束工作流。因此我需要为发散网关、脚本任务和聚合网关设置属性。
在此阶段,我还将向您展示我的工作流程存在一些错误,稍后我将向您展示,一旦我设置了属性,我的工作流程中就不会出现错误,从而向您展示如何验证创建的工作流。
提示 − 请记住,验证器在 Windows → 首选项 → 验证下处于打开状态
以下屏幕截图显示了 eclipse 中的设置。


根据屏幕截图,您可以看到有 4 个错误。第一个错误表示脚本没有操作,然后另一个错误是网关的定义没有定义类型。因此,我们需要删除这些错误才能运行工作流。
我们现在将逐一设置属性,并查看错误消失。
选择第一个网关(diverge)并单击属性,然后单击类型并根据您的要求选择门。

选择网关后,您需要选择一个约束。

单击标记为红色的圆圈,您将看到以下屏幕截图

单击编辑并根据屏幕截图填写详细信息 −


单击"导入"并导入我们将对其执行任何操作的类。在屏幕截图中,我们导入了乘客 POJO,我们将在示例中使用它。

同样,填写另一个约束 − 的详细信息

现在,单击 OK 按钮。

再次单击 OK。现在,选择脚本任务并执行与分流网关相同的过程。
我们刚刚添加了一个 SOP(打印语句)来显示流程。任何 java 或 mvel 代码都可以在脚本任务中编写。

同样,添加第二个约束 − 的代码

最后,您需要为分流网关添加网关类型。

现在,保存工作流文件并转到问题视图。所有问题都将得到解决。

问题视图中没有错误表明,创建的工作流中没有错误。这就是在 jBPM 中创建和验证工作流的方式。
jBPM5 - 示例
我们将在本章中举一个例子来解释如何将 jBPM 付诸实践。手头的任务是使用 jBPM 根据乘客的收入来决定乘客是登上飞机还是火车。
创建项目的步骤与"Hello World"项目的步骤相同。在编辑器中打开 .rf 文件,并查看用红色 − 标记的更改

在这里,我们更改了规则流 id(唯一)并添加了变量 income,因为我们将根据乘客的收入来决定路线。
如何设置变量 −选择红色标记的编辑按钮。

单击添加按钮 −

弹出以下屏幕 −

将名称设置为收入,类型设置为整数。

单击确定。现在您将看到已定义的income变量。

在ProcessTest.java类中需要进行的更改(用于加载和运行流程的类)−

Map<String, Object> params = new HashMap<String, Object>(); params.put("income", 1200); // 启动新的流程实例 ksession.startProcess("vivek.ruleflow", params);
您需要创建一个MAP并在MAP中设置值,然后将该值传递给startProcess重载方法。如图所示,我们更改了规则流 ID,因此在 startProcess 方法中使用了相同的 ID (vivek.ruleflow)。
在运行 ProcessTest.java 类之前,在与 ProcessTest.java 相同的包中创建一个 POJO Passenger.java
public class Passenger { private String name; private int income; getters and setters here }
现在将 ProcessTest.java 类作为 Java 应用程序运行并查看输出 −

更改值 − params.put("income", 900);然后重新运行该类并查看输出的变化。
