jBPM 4 與 Spring 整合的三大核心目標:**服務暴露至 Spring IOC**、**jBPM 環境整合 Spring Context**、**交易管理統一**。本文從架構層面深度解析 SpringConfiguration 如何增強 JbpmConfiguration、Environment 如何持有 Spring Context、Command 模式下的交易攔截器替換機制。
ProcessEngine processEngine = new Configuration().buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
ExecutionService executionService = processEngine.getExecutionService();
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();
ManagementService managementService = processEngine.getManagementService();
<bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration">
<constructor-arg value="be/inze/spring/demo/jbpm.cfg.xml"/>
</bean>
<bean id="processEngine" factory-bean="jbpmConfiguration" factory-method="buildProcessEngine"/>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
<bean id="executionService" factory-bean="processEngine" factory-method="getExecutionService"/>
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService"/>
現在可直接 @Autowired RepositoryService repositoryService 注入使用。
JbpmConfiguration (jBPM 核心配置)
↑
SpringConfiguration (Spring 整合增強)
- 實作 ApplicationContextAware
- 持有 ApplicationContext 參考
public class SpringConfiguration extends JbpmConfiguration implements ApplicationContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
protected Environment openEnvironment() {
Environment env = super.openEnvironment();
// 關鍵:將 Spring Context 封裝為 SpringContext 加入環境
env.setContext(new SpringContext(applicationContext));
return env;
}
}
public class SpringContext implements Context {
private ApplicationContext applicationContext;
public SpringContext(ApplicationContext ac) { this.applicationContext = ac; }
public Object get(String name) { return applicationContext.getBean(name); }
public void set(String name, Object value) { /* 不支援設定 */ }
// ... 其他方法
}

在 jbpm.cfg.xml 的 process-engine-context 中移除:
<hibernate-configuration>
<cfg resource="jbpm.hibernate.cfg.xml"/>
</hibernate-configuration>
<hibernate-session-factory/>
改由 Spring 配置 sessionFactory 並注入 SpringConfiguration (參考方式一)。
所有業務操作封裝為 Command,由 CommandService 執行,通過攔截器鏈處理:
<command-service>
<retry-interceptor/>
<environment-interceptor/>
<standard-transaction-interceptor/> <!-- 原內建交易攔截器 -->
</command-service>

Transaction API
<command-service>
<retry-interceptor/>
<environment-interceptor/>
<spring-transaction-interceptor current="true"/> <!-- 替換為 Spring 交易 -->
</command-service>
Environment 的 SpringContext 獲取 PlatformTransactionManagerTransactionTemplate 回調執行 CommandPROPAGATION_MANDATORY (強制加入現有交易)
在 transaction-context 中配置:
<hibernate-session current="true"/> <!-- 從 TransactionSynchronizationManager 獲取 -->
<!-- 移除 <transaction/> -->
| 層面 | jBPM 內建 | Spring 整合後 |
|---|---|---|
| 服務獲取 | 程式碼 new Configuration() | Spring IOC 注入 |
| 環境上下文 | 僅 Engine/Transaction IOC | + Spring IOC (ApplicationContext) |
| SessionFactory | jBPM 內建管理 | Spring 統一管理 |
| 交易管理 | StandardTransactionInterceptor (Hibernate) | SpringTransactionInterceptor (PlatformTransactionManager) |
| Session 綁定 | 交易內部管理 | ThreadLocal (Spring 同步) |
| 外部服務訪問 | 困難 (需手動查 JNDI) | 直接 @Autowired 任意 Spring Bean |