jBPM-4.4:与Spring集成配置

    技术2026-06-13  0

    jBPM-4.4与Spring集成配置比较容易,这里我使用的是Spring-2.5.6,数据库连接池使用C3P0,将相关的两个jar文件加入到CLASSPATH中。

    jBPM-4.4与Spring集成的配置过程说明如下。

     

    配置

     

    1、修改jbpm.cfg.xml配置文件

    将jbpm.cfg.xml文件中<import resource="jbpm.tx.hibernate.cfg.xml" />一行,修改为 <import resource="jbpm.tx.spring.cfg.xml" />,我们使用Spring的事务管理器,修改后配置文件内容为:

    <?xml version="1.0" encoding="UTF-8"?> <jbpm-configuration> <import resource="jbpm.default.cfg.xml" /> <import resource="jbpm.businesscalendar.cfg.xml" /> <!-- <import resource="jbpm.tx.hibernate.cfg.xml" /> --> <import resource="jbpm.tx.spring.cfg.xml" /> <import resource="jbpm.jpdl.cfg.xml" /> <import resource="jbpm.bpmn.cfg.xml" /> <import resource="jbpm.identity.cfg.xml" /> <!-- Job executor is excluded for running the example test cases. --> <!-- To enable timers and messages in production use, this should be included. --> <!-- <import resource="jbpm.jobexecutor.cfg.xml" /> --> </jbpm-configuration>

     

    2、修改Spring的applicationContext.xml配置文件

    配置文件内容如下所示:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jbpmdb" /> <property name="user" value="jbpm" /> <property name="password" value="jbpm" /> <property name="initialPoolSize" value="3" /> <property name="minPoolSize" value="3" /> <property name="maxPoolSize" value="50" /> <property name="maxIdleTime" value="600" /> <property name="maxStatements" value="100" /> <property name="acquireIncrement" value="3" /> </bean> <bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper" /> <bean id="processEngine" factory-bean="springHelper" factory-method="createProcessEngine" /> <!--Hibernate SessionFatory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>jbpm.repository.hbm.xml</value> <value>jbpm.execution.hbm.xml</value> <value>jbpm.history.hbm.xml</value> <value>jbpm.task.hbm.xml</value> <value>jbpm.identity.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <!-- Transaction Manager --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> <property name="dataSource" ref="dataSource" /> </bean> </beans>

    这里使用MySQL作为流程数据库,需要在dataSource的bean中配置,其他的配置内容非常容易理解。这里面,我们最终的目标是通过Spring的IOC容器来管理jBPM引擎的创建,即在应用中获取到一个org.jbpm.api.ProcessEngine实例即可,在一个应用中通常只有一个流程引擎实例,然后通过这个实例就可以获取到流程提供的6种基本服务:

    org.jbpm.api.RepositoryService org.jbpm.api.ExecutionService org.jbpm.api.ManagementService org.jbpm.api.TaskService org.jbpm.api.HistoryService org.jbpm.api.IdentityService 一般情况下,在开发中不要将org.jbpm.api.ProcessEngine实例暴露给实际开发者,而只是暴露出引擎提供的服务即可。

     

    测试验证

     

    我们测试用例的流程定义如图所示:

     对应的流程定义文件内容如下所示:

    <?xml version="1.0" encoding="UTF-8"?> <process name="MyExample" xmlns="http://jbpm.org/4.4/jpdl"> <on event="start"> <event-listener class="com.umpay.workflow.jbpm.listener.StartupListener"> <field name="status"> <string value="startup check..."/> </field> </event-listener> </on> <start g="354,6,48,48"> <transition g="-102,-16" name="to start decision" to="start decision"> <event-listener class="com.umpay.workflow.jbpm.listener.InitializationListener"> <field name="initialized"> <string value="initialize..."/> </field> </event-listener> </transition> </start> <decision g="413,107,48,48" name="start decision"> <handler class="com.umpay.workflow.jbpm.decision.StartDecision" /> <transition g="-83,-17" name="to check user" to="check user"/> <transition g="-48,-25" name="to error" to="error"/> </decision> <state g="216,183,104,52" name="check user"> <on event="start"> <event-listener class="com.umpay.workflow.jbpm.listener.CheckUserListener"> <field name="state"> <string value="Check user state..."/> </field> </event-listener> </on> <transition g="-128,-8" name="to decide check user" to="decide check user result"/> </state> <decision g="359,271,48,48" name="decide check user result"> <handler class="com.umpay.workflow.jbpm.decision.CheckUserDecision" /> <transition g="-95,-17" name="to check mobile" to="check mobile"/> <transition g="-41,14" name="to error" to="error"/> </decision> <state g="215,349,104,52" name="check mobile"> <on event="start"> <event-listener class="com.umpay.workflow.jbpm.listener.CheckMobileListener"> <field name="online"> <string value="Check mobile number..."/> </field> </event-listener> </on> <transition g="-146,-6" name="to decide check mobile" to="decide check mobile result"/> </state> <decision g="337,435,48,48" name="decide check mobile result"> <handler class="com.umpay.workflow.jbpm.decision.CheckMobileDecision" /> <transition g="-98,-21" name="to do transaction" to="do transaction"/> <transition g="-39,9" name="to error" to="error"/> </decision> <state g="217,516,112,52" name="do transaction"> <on event="start"> <event-listener class="com.umpay.workflow.jbpm.listener.DoTransactionListener"> <field name="operation"> <string value="Do transaction..."/> </field> </event-listener> </on> <transition g="-101,-17" name="to last decision" to="last decision"/> </state> <decision g="312,599,48,48" name="last decision"> <handler class="com.umpay.workflow.jbpm.decision.DoTransactionDecision" /> <transition g="-41,-17" name="to end" to="end"/> <transition g="-41,-1" name="to error" to="error"/> </decision> <end-error g="475,675,48,48" name="error"/> <end g="242,675,48,48" name="end"> <on event="start"> <event-listener class="com.umpay.workflow.jbpm.listener.ShutdownHookListener"> <field name="saveThings"> <string value="S:shutdown..."/> </field> </event-listener> </on> </end> </process>

     

    基于该流程定义,实现的测试用例如下所示:

    package com.umpay.workflow.jbpm.process; import junit.framework.TestCase; import org.jbpm.api.Execution; import org.jbpm.api.ProcessEngine; import org.jbpm.api.ProcessInstance; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyProcessWithSpringTest extends TestCase { private ProcessEngine processEngine; String deploymentId; protected void setUp() throws Exception { super.setUp(); ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml"); ctx.start(); this.processEngine = (ProcessEngine) ctx.getBean("processEngine"); deploymentId = this.processEngine .getRepositoryService() .createDeployment() .addResourceFromClasspath( "com/umpay/workflow/jbpm/process/process.jpdl.xml") .deploy(); } protected void tearDown() throws Exception { this.processEngine.getRepositoryService().deleteDeploymentCascade( deploymentId); super.tearDown(); } public void testMyProcess() { // start a process instance ProcessInstance processInstance = this.processEngine .getExecutionService().startProcessInstanceByKey("MyExample"); // state : check user assertEquals("check user", processInstance.findActiveActivityNames() .iterator().next()); Execution execution = processInstance .findActiveExecutionIn("check user"); // state : check mobile processInstance = this.processEngine.getExecutionService() .signalExecutionById(execution.getId()); execution = processInstance.findActiveExecutionIn("check mobile"); assertEquals("check mobile", processInstance.findActiveActivityNames() .iterator().next()); // state : do transaction processInstance = this.processEngine.getExecutionService() .signalExecutionById(execution.getId()); execution = processInstance.findActiveExecutionIn("do transaction"); assertEquals("do transaction", processInstance .findActiveActivityNames().iterator().next()); processInstance = this.processEngine.getExecutionService() .signalExecutionById(execution.getId()); assertEquals(true, processInstance.findActiveActivityNames().isEmpty()); // ended assertEquals(Execution.STATE_ENDED, processInstance.getState()); } }

    最新回复(0)