68.3. Spring との統合
Spring フレームワークでプロセスエンジンを使用する方法はいくつかありますが、最も頻繁に使用されるのは 2 つのアプローチです。
- Runtime Manager API の直接使用
- プロセスエンジンサービスの使用
どちらのアプローチもテストされ、有効です。
アプリケーションが 1 つのランタイムマネージャーのみを使用する必要がある場合は、ダイレクト Runtime Manager API を使用します。これは、Spring アプリケーションでプロセスエンジンを使用する最も簡単な方法となるためです。
アプリケーションがランタイムマネージャーの複数のインスタンスを使用する必要がある場合は、プロセスエンジンサービスを使用して、動的ランタイム環境を提供することでベストプラクティスをカプセル化します。
68.3.1. Spring でのランタイムマネージャー API の直接使用
ランタイムマネージャーは、プロセスエンジンとタスクサービスを同期して管理します。ランタイムマネージャーの詳細は、「ランタイムマネージャー」を参照してください。
Red Hat Process Automation Manager は、Spring MVC アプリケーションからの EJB タイマーの使用をサポートしていません。
Spring フレームワークでランタイムマネージャーを設定するには、以下のファクトリー Bean を使用します。
-
org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean
-
org.kie.spring.factorybeans.RuntimeManagerFactoryBean
-
org.kie.spring.factorybeans.TaskServiceFactoryBean
これらのファクトリー Bean は、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
-
assets
-
releaseId
-
groupId, artifactId, version
タイプ DEFAULT
、DEFAULT_KJAR
、および DEFAULT_KJAR_CL
については、以下のパラメーターを指定して永続性を設定する必要もあります。
- エンティティーマネージャーファクトリー
- トランザクションマネージャー
永続性やトランザクションサポートがこのトランザクションマネージャーを基に設定されるため、トランザクションマネージャーは Spring トランザクションマネージャーである必要があります。
任意で、EntityManagerFactory
から新規インスタンスを作成する代わりに EntityManager
インスタンスを指定できます。たとえば、Spring から共有エンティティーマネージャーを使用できます。
その他のプロパティーはすべて任意です。ランタイム環境の選択したタイプで決定されるデフォルト値を上書きできます。
68.3.1.2. RuntimeManagerFactoryBean
Bean
RuntimeManagerFactoryBean
ファクトリー Bean は、提供された RuntimeEnvironment
インスタンスに基づいて、指定したタイプの RuntimeManager
インスタンスを生成します。
サポートされるタイプは、ランタイムマネージャーの戦略に対応します。
-
SINGLETON
-
PER_REQUEST
-
PER_PROCESS_INSTANCE
タイプが指定されていない場合のデフォルトタイプは SINGLETON
です。
すべてのランタイムマネージャーは一意に特定する必要があるため、識別子は必須プロパティーです。このファクトリーによって作成されたすべてのインスタンスがキャッシュされるため、destroy メソッド (close()
) を使用して適切に破棄できます。
68.3.1.3. TaskServiceFactoryBean
Bean
TaskServiceFactoryBean
ファクトリー Bean は、指定のプロパティーに基づいて TaskService
のインスタンスを生成します。以下の必須プロパティーを指定する必要があります。
- エンティティーマネージャーファクトリー
- トランザクションマネージャー
永続性やトランザクションサポートがこのトランザクションマネージャーを基に設定されるため、トランザクションマネージャーは Spring トランザクションマネージャーである必要があります。
任意で、EntityManagerFactory
から新規インスタンスを作成する代わりに EntityManager
インスタンスを指定できます。たとえば、Spring から共有エンティティーマネージャーを使用できます。
タスクサービスインスタンスに、任意の追加プロパティーを設定することもできます。
-
userGroupCallback
: タスクサービスが使用する必要のあるUserGroupCallback
の実装。デフォルト値はMVELUserGroupCallbackImpl
です。 -
userInfo
: タスクサービスが使用する必要のあるUserInfo
の実装。デフォルト値はDefaultUserInfo
です。 -
listener
: タスクのさまざまな操作で通知する必要があるTaskLifeCycleEventListener
リスナーのリスト
このファクトリー Bean は、タスクサービスの単一のインスタンスを作成します。設計上、このインスタンスは Spring 環境のすべての Bean 間で共有される必要があります。
68.3.1.4. Spring アプリケーションを使用したランタイムマネージャーの設定
以下の手順は、Spring アプリケーション内の単一のランタイムマネージャーの完全な設定例になります。
手順
エンティティーマネージャーファクトリーおよびトランザクションマネージャーを設定します。
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 でサポート) (ユニットテスト用またはサーブレットコンテナー用)
-
org.jbpm.persistence.spring.jta
永続ユニットのエンティティーマネージャーファクトリー
ビジネスプロセスリソースを設定します。
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>
これらの設定は、実行可能な 1 つのプロセスを定義します。リソースの名前は
sample.bpmn
で、クラスパスで利用可能でなければなりません。クラスパスを単純な方法で使用して、プロセスエンジンを試すためのリソースを追加できます。エンティティーマネージャー、トランザクションマネージャー、およびリソースを使用して
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>
これらの設定は、ランタイムマネージャーのデフォルトのランタイム環境を定義します。
環境に基づいて
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>
結果
これらの手順を完了した後、EntityManagerFactory
クラスおよび JTA トランザクションマネージャーを使用して、ランタイムマネージャーを使用して Spring 環境でプロセスを実行できます。
リポジトリー では、異なるストラテジーの完全 Spring 設定ファイルを確認できます。
68.3.1.5. Spring フレームワークのランタイムマネージャーの追加設定オプション
「Spring アプリケーションを使用したランタイムマネージャーの設定」で説明されているように、EntityManagerFactory
クラスと JTA トランザクションマネージャーの設定の他に、Spring フレームワークのランタイムマネージャーに他の設定オプションを使用できます。
-
JTA および
SharedEntityManager
クラス -
ローカル永続ユニットおよび
EntityManagerFactory
クラス -
ローカル永続ユニットおよび
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 アプリケーション内のプロセスエンジンサービスの完全な設定例です。
手順
トランザクションを設定します。
spring.xml
ファイルでのトランザクションの設定<context:annotation-config /> <tx:annotation-driven /> <tx:jta-transaction-manager /> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
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>
セキュリティーおよびユーザーおよびグループの情報プロバイダーを設定します。
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"/>
ランタイムマネージャーファクトリーを設定します。このファクトリーは 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>
プロセスエンジンサービスを 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 アプリケーションはプロセスエンジンサービスを使用できます。