68.2. 与 CDI 集成
流程引擎支持自动与 CDI 集成。您可以在 CDI 框架中使用大多数 API,而无需任何修改。
进程引擎还提供一些专门用于 CDI 容器的专用模块。最重要的模块是 jbpm-services-cdi,它为处理引擎服务提供 CDI 封装器。您可以使用这些打包程序在 CDI 应用程序中集成进程引擎。模块提供以下一组服务:
-
DeploymentService -
ProcessService -
UserTaskService -
RuntimeDataService -
DefinitionService
这些服务可用于在任何其他 CDI Bean 中注入。
68.2.1. CDI 部署服务 复制链接链接已复制到粘贴板!
DeploymentService 服务在运行时环境中部署并取消部署部署单元。当您使用这个服务部署单元时,部署单元就可以执行,并创建一个 RuntimeManager 实例。您还可以使用 DeploymentService 检索以下对象:
-
给定部署 ID 的
RuntimeManager实例 -
代表给定部署 ID 的完整部署单元的
DeployedUnit实例 - 部署服务已知的所有部署单元列表
默认情况下,部署服务不会将部署单元的信息保存到任何持久性存储。在 CDI 框架中,使用该服务的组件可以保存和恢复部署单元信息,例如使用数据库、文件系统或存储库。
部署服务会在部署和取消部署中触发 CDI 事件。使用服务的组件可以处理这些事件来存储部署,并在取消部署时将其从存储中移除。
-
部署单元时会触发带有
@Deployqualifier 的DeploymentEvent -
带有
@Undeployqualifier 的DeploymentEvent在单元的 undeployment 上触发
您可以使用 CDI 观察程序机制来获取这些事件的通知。
以下示例收到单元部署中的通知,并可以保存部署:
部署事件处理示例
public void saveDeployment(@Observes @Deploy DeploymentEvent event) {
// Store deployed unit information
DeployedUnit deployedUnit = event.getDeployedUnit();
}
public void saveDeployment(@Observes @Deploy DeploymentEvent event) {
// Store deployed unit information
DeployedUnit deployedUnit = event.getDeployedUnit();
}
以下示例在部署单元时收到通知,并可从存储中删除部署:
处理非部署事件的示例
public void removeDeployment(@Observes @Undeploy DeploymentEvent event) {
// Remove deployment with the ID event.getDeploymentId()
}
public void removeDeployment(@Observes @Undeploy DeploymentEvent event) {
// Remove deployment with the ID event.getDeploymentId()
}
DeploymentService 服务有几个实现,因此您必须使用限定符来指示 CDI 容器注入特定的实施。每一实施部署都必须存在 DeploymentUnit 的 匹配。
流程引擎提供 KmoduleDeploymentService 实施。这种实现旨在与 KmoduleDeploymentUnits 合作,它们是 KJAR 文件中所含的小描述符。这个实现是大多数用例中典型的解决方案。此实施的限定符是 @Kjar。
68.2.2. CDI 的表单供应商服务 复制链接链接已复制到粘贴板!
FormProviderService 服务提供对表单的访问,通常显示在用户界面中用于进程表单和用户任务表单的用户界面。
该服务依赖于隔离形式的供应商的概念,可提供不同功能并由不同的技术提供支持。FormProvider 接口描述了表单供应商的合同。
FormProvider 接口的定义
FormProvider 接口的实现必须定义优先级值。当 FormProviderService 服务需要呈现表单时,它会按优先级顺序调用可用提供程序。
优先级越低,提供商获得的优先级越高。例如,在优先级为 10 的供应商之前,评估优先级为 5 的供应商。对于每个所需表单,服务按照其优先级顺序迭代可用的提供程序,直至其中之一来提供内容。在最糟糟的情况中,返回一个简单的基于文本的表单。
进程引擎提供 FormProvider 的以下实现:
- 提供 Form Modeller 工具中创建的表单的供应商,优先级为 2
- 基于 FreeMarker 的实施,它支持流程和任务表单,优先级为 3
- 默认表单供应商返回简单的基于文本的表单,如果不存在其他供应商提供任何内容,其使用方法为 1000
68.2.3. CDI 运行时数据服务 复制链接链接已复制到粘贴板!
RuntimeDataService 服务提供对在运行时可用的数据的访问,包括以下数据:
- 要执行的可用进程,带有各种过滤器
- 活跃的进程实例,带有不同的过滤器
- 进程实例历史记录
- 进程实例变量
- 进程实例的活跃和完成节点
RuntimeDataService 的默认实现会观察部署事件,并索引所有部署的进程以将其公开给调用组件。
68.2.4. CDI 定义服务 复制链接链接已复制到粘贴板!
DefinitionService 服务提供对作为 BPMN2 XML 定义一部分存储的进程详细信息的访问。
在使用提供信息的任何方法前,调用 buildProcessDefinition() 方法,以使用从 BPMN2 内容检索的进程信息填充存储库。
BPMN2DataService 实现提供对以下数据的访问:
- 给定进程定义过程的整体描述
- 在进程定义中找到的所有用户任务的集合
- 有关用户任务节点定义的输入的信息
- 有关为用户任务节点定义的输出的信息
- 在给定进程定义中定义的可重用进程的 ID(call 活动)
- 有关在给定进程定义中定义的进程变量的信息
有关包含在进程定义中的所有组织实体(用户和组)的信息。根据具体进程定义,用户和组返回的值可包含以下信息:
- 实际用户或组名称
-
用于在运行时获取实际用户或组名称的进程变量,例如:
#{manager}
68.2.5. CDI 集成配置 复制链接链接已复制到粘贴板!
要在 CDI 框架中使用 jbpm-services-cdi 模块,您必须提供一些 bean 来满足所含服务实施的依赖项。
根据使用场景,需要几个 Bean:
- 实体管理器和实体管理器工厂
- 用于人工任务的用户组回调
- 身份提供程序将经过身份验证的用户信息传递给服务
在 JEE 环境中运行(如红帽 JBoss EAP)时,以下制作者 bean 满足 jbpm-services-cdi 模块的所有要求。
制作者 bean 满足 JEE 环境中的 jbpm-services-cdi 模块的所有要求
应用的 Bean.xml 文件必须为用户组 info 回调启用正确的替代选择。这种替代选择基于 @Selectable qualifier。
在 Bean.xml 文件'中,为用户组信息回调的定义
org.jbpm.kie.services.cdi.producer.JAASUserGroupInfoProducer 是一个示例值。这个值通常适合于红帽 JBoss EAP,因为它可重复利用应用服务器上的安全设置,无论服务器使用哪种安全方法,如 LDAP 或数据库。
另外,您还可以提供一些其他制作者来提供 WorkItemHandlers 和 Process、Agenda、WorkingMemory 事件监听程序。您可以通过实现以下接口来提供这些组件:
处理引擎与 CDI 集成的工作项目处理程序制作界面
用于处理引擎与 CDI 集成的事件监听程序制作者接口
实施这两个接口的 Bean 会在运行时收集并在 RuntimeManager 类构建 KieSession 实例时调用。
68.2.5.1. 作为 CDI Bean 的运行时管理器 复制链接链接已复制到粘贴板!
您可以将 RuntimeManager 类作为 CDI Bean 注入应用程序中的任何其他 CDI Bean。必须正确生成 RuntimeEnvironment 类,以启用 RuntimeManager 实例的正确初始化。
以下 CDI 限定符引用现有的运行时管理器策略:
-
@Singleton -
@PerRequest -
@PerProcessInstance
有关运行时管理器的详情,请参考 第 66.2 节 “运行时管理器”。
虽然您可以直接注入 RuntimeManager 类,但对于大多数框架用例(如 CDI、EJB 或 Spring)的解决方案正在使用服务。流程引擎服务使用运行时管理器实施许多最佳实践。
要使用运行时管理器,您必须将 RuntimeEnvironment 类添加到 第 68.2.5 节 “CDI 集成配置” 部分中定义的 producer 中。
提供 RuntimeEnvironment 类的 producer bean
在本例中,单一制作者方法可以通过在方法级别上指定所有运行时管理器策略,为所有运行时管理器策略提供 RuntimeEnvironment 类。
当完整的制作者可用时,RuntimeManager 类可以注入到应用程序的 CDI bean 中:
注入 RuntimeManager 类
如果您注入 RuntimeManager 类,则应用程序中只能有一个 RuntimeManager 实例。在典型的情形中,使用 DeploymentService 服务根据需要创建 RuntimeManager 实例。
作为 DeploymentService 的替代方案,您可以注入 RuntimeManageronnectionFactory y 类,然后应用程序就可以使用它来创建 RuntimeManager 实例。在这种情况下,仍需要 EnvironmentProducer 定义。以下示例显示了一个简单的 ProcessEngine bean。
ProcessEngine bean 示例