68.3. 与 Spring 集成


虽然可以通过几种方式将流程引擎与 Spring 框架一起使用,但最常使用两种方法

  • 直接使用 Runtime Manager API
  • 使用进程引擎服务

这两种方法都经过测试并有效。

如果您的应用程序只需要使用一个运行时管理器,请使用直接运行时管理器 API,因为这是在 Spring 应用程序中使用流程引擎的最简单方法。

如果您的应用程序需要使用运行时管理器的多个实例,请使用进程引擎服务,通过提供动态运行时环境来封装最佳实践。

68.3.1. 在 Spring 中直接使用运行时管理器 API

运行时管理器在同步过程中管理进程引擎和任务服务。有关运行时管理器的详情,请参考 第 66.2 节 “运行时管理器”

注意

Red Hat Process Automation Manager 不支持使用 Spring MVC 应用程序中的 EJB 计时器。

要在 Spring 框架中设置运行时管理器,请使用以下 factoryan:

  • org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean
  • org.kie.spring.factorybeans.RuntimeManagerFactoryBean
  • org.kie.spring.factorybeans.TaskServiceFactoryBean

这些 factoryan 提供了一种标准方法来为您的 Spring 应用程序配置 spring.xml 文件。

68.3.1.1. RuntimeEnvironmentFactoryBean bean

RuntimeEnvironmentFactoryBean 工厂 bean 生成 RuntimeEnvironment 的实例。创建 RuntimeManager 实例需要这些实例。

bean 支持创建带有不同默认配置的以下 RuntimeEnvironment 实例类型:

  • DEFAULT :运行时管理器的默认设置或最常用的配置
  • EMPTY :您可以手动配置完全空环境
  • DEFAULT_IN_MEMORY :与 DEFAULT 相同的配置,但没有运行时引擎的持久性
  • DEFAULT_KJAR :与 DEFAULT 相同的配置,但资产从 KJAR 工件(由发行版本 ID 或 GAV 值标识)中加载
  • DEFAULT_KJAR_CL :配置基于 KJAR 构件中的 kmodule.xml 描述符构建

必要属性取决于所选的类型。但是,所有类型都必须显示相关信息。这个要求意味着必须提供以下信息之一:

  • knowledgeBase
  • 资产
  • releaseId
  • GroupId, artifactId, version

对于 DEFAULTDEFAULT_KJARDEFAULT_KJAR_CL 类型,还必须通过提供以下参数来配置持久性:

  • 实体管理器工厂
  • 事务管理器

事务管理器必须是 Spring 事务管理器,因为基于此事务管理器对持久性和事务支持进行配置。

另外,您还可以提供一个 EntityManager 实例,而不是从 EntityManagerFactory 创建新实例,例如,您可以使用 Spring 的共享实体管理器。

所有其他属性都是可选的。它们可以覆盖由所选运行时环境类型决定的默认值。

68.3.1.2. RuntimeManageronnectionFactoryyBean bean

RuntimeManagerFactoryBean factoryan 根据提供的 RuntimeEnvironment 实例生成给定类型的 RuntimeManager 实例。

支持的类型与运行时管理器策略对应:

  • 单例
  • PER_REQUEST
  • PER_PROCESS_INSTANCE

如果没有指定类型,默认类型是 SINGLETON

标识符是一个强制属性,因为每个运行时管理器都必须唯一标识。此工厂创建的所有实例都会被缓存,因此可以使用 destroy 方法正确处理它们(关闭())。

68.3.1.3. TaskServiceFactoryBean an

TaskServiceFactoryBean factoryan 根据给定属性生成 TaskService 实例。您必须提供以下强制属性:

  • 实体管理器工厂
  • 事务管理器

事务管理器必须是 Spring 事务管理器,因为基于此事务管理器对持久性和事务支持进行配置。

另外,您还可以提供一个 EntityManager 实例,而不是从 EntityManagerFactory 创建新实例,例如,您可以使用 Spring 的共享实体管理器。

您还可以为任务服务实例设置额外的可选属性:

  • userGroupCallback :任务服务必须使用的 UserGroupCallback 的实施,默认值为 MVELUserGroupCallbackImpl
  • UserInfo :任务服务必须使用的 UserInfo 实施,默认值为 DefaultUserInfo
  • 侦听器TaskLifeCycleEventListener 监听器列表,必须在各种任务中获得通知

此 factoryan 创建任务服务的一个实例。按照设计,此实例必须在 Spring 环境中的所有 Bean 中共享。

68.3.1.4. 使用 Spring 应用程序配置示例运行时管理器

以下流程是 Spring 应用程序中的一个运行时管理器的完整配置示例。

流程

  1. 配置实体管理器工厂和事务管理器:

    spring.xml 文件中配置实体管理器工厂和事务管理器

    <bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
    </bean>
    
    <bean id="jbpmEM" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
      <property name="entityManagerFactory" ref="jbpmEMF"/>
    </bean>
    
    <bean id="narayanaUserTransaction" factory-method="userTransaction" class="com.arjuna.ats.jta.UserTransaction" />
    
    <bean id="narayanaTransactionManager" factory-method="transactionManager" class="com.arjuna.ats.jta.TransactionManager" />
    
    <bean id="jbpmTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
      <property name="transactionManager" ref="narayanaTransactionManager" />
      <property name="userTransaction" ref="narayanaUserTransaction" />
    </bean>

    这些设置定义了以下持久性配置:

    • JTA 事务管理器(由 Narayana JTA 提供支持,用于单元测试或 servlet 容器)
    • org.jbpm.persistence.spring.jta persistence 单元的实体管理器工厂
  2. 配置业务流程资源:

    spring.xml 文件中配置业务流程资源

    <bean id="process" factory-method="newClassPathResource" class="org.kie.internal.io.ResourceFactory">
      <constructor-arg>
        <value>jbpm/processes/sample.bpmn</value>
      </constructor-arg>
    </bean>

    这些设置定义可用于执行的单个进程。资源名称是 sample.bpmn,它必须在类路径上可用。您可以将类路径用作包含尝试进程引擎的资源的简单方法。

  3. 使用实体管理器、事务管理器和资源配置 RuntimeEnvironment 实例:

    spring.xml 文件中配置 RuntimeEnvironment 实例

    <bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
      <property name="type" value="DEFAULT"/>
      <property name="entityManagerFactory" ref="jbpmEMF"/>
      <property name="transactionManager" ref="jbpmTxManager"/>
      <property name="assets">
        <map>
          <entry key-ref="process"><util:constant static-field="org.kie.api.io.ResourceType.BPMN2"/></entry>
        </map>
      </property>
    </bean>

    这些设置定义了运行时管理器的默认运行时环境。

  4. 根据环境创建一个 RuntimeManager 实例:

    <bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean" destroy-method="close">
      <property name="identifier" value="spring-rm"/>
      <property name="runtimeEnvironment" ref="runtimeEnvironment"/>
    </bean>

结果

在这些步骤后,您可以使用运行时管理器使用实体管理器和 JTA 事务管理器在 Spring 环境中执行进程。

您可以在 存储库 中找到针对不同策略的完整 Spring 配置文件。

68.3.1.5. Spring 框架中的运行时管理器的额外配置选项

除了使用 EntityManagerFactory 类和 JTA 事务管理器的配置外,如 第 68.3.1.4 节 “使用 Spring 应用程序配置示例运行时管理器” 所述,您还可以使用 Spring 框架中的运行时管理器的其他配置选项:

  • JTA 和 SharedEntityManager
  • 本地持久性单元和 实体管理器工厂
  • 本地持久性单元和 SharedEntityManager

如果您的应用程序配置了本地持久性单元,并使用 AuditService 服务查询进程引擎历史记录数据,您必须将 org.kie.api.runtime.EnvironmentName.USE_LOCAL_TRANSACTIONS 环境条目添加到 RuntimeEnvironment 实例配置:

spring.xml 文件中为本地持久性单元的 RuntimeEnvironment 实例配置

<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
...
    <property name="environmentEntries" ref="env" />
  </bean>
  ...

  <util:map id="env" key-type="java.lang.String" value-type="java.lang.Object">
		<entry>
			<key>
				<util:constant
					static-field="org.kie.api.runtime.EnvironmentName.USE_LOCAL_TRANSACTIONS" />
			</key>
			<value>true</value>
		</entry>
	</util:map>

您可以在存储库中找到更多配置选项示例: 配置文件和 测试案例

68.3.2. 使用 Spring 处理引擎服务

您可能想要创建一个动态的 Spring 应用程序,您可以在不重启应用程序的情况下添加和删除业务资产,如流程定义、数据模型、规则和表单。

在这种情况下,使用流程引擎服务。进程引擎服务被设计为与框架无关,单独的模块可在所需框架的附加中实现。

jbpm-kie-services 模块包含服务的代码逻辑。Spring 应用程序可以使用这些纯 Java 服务。

您必须在 Spring 应用程序中添加的唯一代码来配置流程引擎服务,这是 IdentityProvider 接口的实现。这种实现取决于您的安全配置。以下实现示例使用 Spring Security,但可能没有涵盖 Spring 应用程序的所有可用安全功能。

使用 Spring Security 实施 IdentityProvider 接口

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.kie.internal.identity.IdentityProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;

public class SpringSecurityIdentityProvider implements IdentityProvider {

	public String getName() {

		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (auth != null && auth.isAuthenticated()) {
			return auth.getName();
		}
		return "system";
	}

	public List<String> getRoles() {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (auth != null && auth.isAuthenticated()) {
			List<String> roles = new ArrayList<String>();

			for (GrantedAuthority ga : auth.getAuthorities()) {
				roles.add(ga.getAuthority());
			}

			return roles;
		}

		return Collections.emptyList();
	}

	public boolean hasRole(String role) {
		return false;
	}

}

68.3.2.1. 使用 Spring 应用程序配置流程引擎服务

以下流程是 Spring 应用程序内处理引擎服务的完整配置示例。

流程

  1. 配置转换:

    spring.xml 文件中配置事务

    <context:annotation-config />
    <tx:annotation-driven />
    <tx:jta-transaction-manager />
    
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

  2. 配置 JPA 和持久性:

    spring.xml 文件中配置 JPA 和持久性

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="transactionManager">
       <property name="persistenceXmlLocation" value="classpath:/META-INF/jbpm-persistence.xml" />
    </bean>

  3. 配置安全性和用户和组群信息供应商:

    spring.xml 文件中配置安全性和组信息提供程序

    <util:properties id="roleProperties" location="classpath:/roles.properties" />
    
    <bean id="userGroupCallback" class="org.jbpm.services.task.identity.JBossUserGroupCallbackImpl">
      <constructor-arg name="userGroups" ref="roleProperties"></constructor-arg>
    </bean>
    
    <bean id="identityProvider" class="org.jbpm.spring.SpringSecurityIdentityProvider"/>

  4. 配置运行时管理器工厂。这个因素是 Spring 上下文了解,因此它能够以正确的方式与 Spring 容器交互,并支持必要的服务,包括事务命令服务和任务服务:

    spring.xml 文件中配置运行时管理器工厂

    <bean id="runtimeManagerFactory" class="org.kie.spring.manager.SpringRuntimeManagerFactoryImpl">
      <property name="transactionManager" ref="transactionManager"/>
      <property name="userGroupCallback" ref="userGroupCallback"/>
    </bean>
    
    <bean id="transactionCmdService" class="org.jbpm.shared.services.impl.TransactionalCommandService">
      <constructor-arg name="emf" ref="entityManagerFactory"></constructor-arg>
    </bean>
    
    <bean id="taskService" class="org.kie.spring.factorybeans.TaskServiceFactoryBean" destroy-method="close">
      <property name="entityManagerFactory" ref="entityManagerFactory"/>
      <property name="transactionManager" ref="transactionManager"/>
      <property name="userGroupCallback" ref="userGroupCallback"/>
      <property name="listeners">
        <list>
          <bean class="org.jbpm.services.task.audit.JPATaskLifeCycleEventListener">
            <constructor-arg value="true"/>
          </bean>
        </list>
      </property>
    </bean>

  5. 将流程引擎服务配置为 Spring Bean:

    spring.xml 文件中将进程引擎服务配置为 Spring Bean

    <!-- Definition service -->
    <bean id="definitionService" class="org.jbpm.kie.services.impl.bpmn2.BPMN2DataServiceImpl"/>
    
    <!-- Runtime data service -->
    <bean id="runtimeDataService" class="org.jbpm.kie.services.impl.RuntimeDataServiceImpl">
      <property name="commandService" ref="transactionCmdService"/>
      <property name="identityProvider" ref="identityProvider"/>
      <property name="taskService" ref="taskService"/>
    </bean>
    
    <!-- Deployment service -->
    <bean id="deploymentService" class="org.jbpm.kie.services.impl.KModuleDeploymentService" depends-on="entityManagerFactory" init-method="onInit">
      <property name="bpmn2Service" ref="definitionService"/>
      <property name="emf" ref="entityManagerFactory"/>
      <property name="managerFactory" ref="runtimeManagerFactory"/>
      <property name="identityProvider" ref="identityProvider"/>
      <property name="runtimeDataService" ref="runtimeDataService"/>
    </bean>
    
    <!-- Process service -->
    <bean id="processService" class="org.jbpm.kie.services.impl.ProcessServiceImpl" depends-on="deploymentService">
      <property name="dataService" ref="runtimeDataService"/>
      <property name="deploymentService" ref="deploymentService"/>
    </bean>
    
    <!-- User task service -->
    <bean id="userTaskService" class="org.jbpm.kie.services.impl.UserTaskServiceImpl" depends-on="deploymentService">
      <property name="dataService" ref="runtimeDataService"/>
      <property name="deploymentService" ref="deploymentService"/>
    </bean>
    
    <!-- Register the runtime data service as a listener on the deployment service so it can receive notification about deployed and undeployed units -->
    <bean id="data" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="deploymentService">
      <property name="targetObject" ref="deploymentService"></property>
      <property name="targetMethod"><value>addListener</value></property>
      <property name="arguments">
      <list>
          <ref bean="runtimeDataService"/>
      </list>
      </property>
    </bean>

结果

您的 Spring 应用程序可以使用流程引擎服务。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.