Spring ,SpringModule和JBPM3.1 整合

尝试了将jbpm和spring进行结合,主要参考http://betafox.iteye.com/blog/177649来进行。

Spring, Springmodules, JBPM持久化集成理解系列一

 

 

【本系列如需转载,请注明作者及出处】

 

本系列文章假设阅者具备以下知识:
1,ThreadLocal相关知识
2,Spring持久化,事务管理相关知识
3,Hibernate 持久化相关知识
4,Jbpm 持久化相关知识
5,Springmodules项目相关知识
6,相关J2EE知识


且具备以下材料:
1,Spring源代码
2,Hibernate源代码
3,Jbpm源代码
4,Springmodules源代码

配置文件如下:

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:util="http://www.springframework.org/schema/util"  
  5.     xmlns:jee="http://www.springframework.org/schema/jee"  
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xmlns:aop="http://www.springframework.org/schema/aop"  
  8.     xmlns:lang="http://www.springframework.org/schema/lang"  
  9.     xsi:schemaLocation="   
  10. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   
  11. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd   
  12. http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd   
  13. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd   
  14. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd   
  15. http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd"   
  16.     default-autowire="byName">  
  17.   
  18.     <bean id="workflow1"  
  19.         class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean">  
  20.         <property name="definitionLocation"  
  21.             value="classpath:jbpm/processes/processdefinition.xml" />  
  22.     </bean>  
  23.   
  24.     <!-- jBPM configuration-->  
  25.     <bean id="jbpmConfiguration"  
  26.         class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">  
  27.         <property name="sessionFactory" ref="sessionFactory" />  
  28.         <property name="configuration" value="classpath:jbpm.cfg.xml" />  
  29.   
  30.         <property name="processDefinitions">  
  31.             <list>  
  32.                 <ref local="workflow1" />  
  33.             </list>  
  34.         </property>  
  35.         <!--    
  36.             <property name="createSchema" value="true" />  
  37.             <property name="dropSchema" value="true" />  
  38.         -->  
  39.     </bean>  
  40.   
  41.     <!-- jBPM template -->  
  42.     <bean id="jbpmTemplate"  
  43.         class="org.springmodules.workflow.jbpm31.JbpmTemplate">  
  44.         <constructor-arg index="0" ref="jbpmConfiguration" />  
  45.         <constructor-arg index="1" ref="workflow1" />  
  46.     </bean>  
  47.   
  48. </beans>  

 在casspath下添加了jbpm.cfg.xml,内容是从default.jbpm.cfg.xml中复制过来的:

Xml代码
  1. <jbpm-configuration>  
  2.   
  3.     <jbpm-context name="default.jbpm.context">  
  4.   
  5.         <service name="persistence"  
  6.             factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" />  
  7.         <service name="message"  
  8.             factory="org.jbpm.msg.db.DbMessageServiceFactory" />  
  9.         <service name="scheduler"  
  10.             factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />  
  11.         <service name="logging"  
  12.             factory="org.jbpm.logging.db.DbLoggingServiceFactory" />  
  13.         <service name="authentication"  
  14.             factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />  
  15.     </jbpm-context>  
  16.   
  17.   
  18.     <!-- 不再使用<string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />-->  
  19.     <string name="resource.business.calendar"  
  20.         value="org/jbpm/calendar/jbpm.business.calendar.properties" />  
  21.     <string name="resource.default.modules"  
  22.         value="org/jbpm/graph/def/jbpm.default.modules.properties" />  
  23.     <string name="resource.converter"  
  24.         value="org/jbpm/db/hibernate/jbpm.converter.properties" />  
  25.     <string name="resource.action.types"  
  26.         value="org/jbpm/graph/action/action.types.xml" />  
  27.     <string name="resource.node.types"  
  28.         value="org/jbpm/graph/node/node.types.xml" />  
  29.     <string name="resource.parsers"  
  30.         value="org/jbpm/jpdl/par/jbpm.parsers.xml" />  
  31.     <string name="resource.varmapping"  
  32.         value="org/jbpm/context/exe/jbpm.varmapping.xml" />  
  33.   
  34. </jbpm-configuration>  

 

在配置过程中也遇到了一些问题。

问题一:系统报找不到 default.jbpm.context。

解决方法:在自己的jbpm.cfg.xml中设置

Xml代码
  1. jbpm-context name="default.jbpm.context"  
jbpm-context name="default.jbpm.context"

问题二:系统报找不到hibernate.cfg.xml。

解决方法:我的系统里hibernate配置放在spring的配置文件里,没有使用hibernate.cfg.xml。跟踪DbPersistenceServiceFactory和LocalJbpmConfigurationFactoryBean.afterPropertiesSet发现问题出在jbpmContext构建时需要获取持久层,如果sessionFactory存在则不会去读取hibernate.cfg.xml,除了在配置jbpmConfiguration时要设置sessionFactory外,如果jbpm的数据库表已经存在,则不要设置createSchema和dropSchema否则会报错。按上面的配置文件设置后,不会再去读取hibernate.cfg.xml,可以注释掉jbpm.cfg.xml中的resource.hibernate.cfg.xml。

注意:如果使用这种配置方式,省略了hibernate.cfg.xml文件,但如果调用jbpmConfiguration.createSchema();jbpmConfiguration.dropSchema();等方法还是会出错,跟踪源码可以发现这些方法都会调用DbPersistenceServiceFactory.getConfiguration()方法,这个方法会去读取hibernate.cfg.xml。我们可以使用jbpm-db\build\mysql\scripts\下的脚本手工创建或删除数据库,这在做单元测试时稍显麻烦。

问题三:jbpm-identity中有User.hbm.xml,这个名称与我系统中原有的User.hbml.xml冲突,尽管他们不在同一个包中,但还是产生了冲突。只能调整一下自己的代码了。

spring配置文件中配置流程定义的xml有些多余,反而使系统在启动的时候更新数据库里的流程定义。完全可以将流程部署到数据库。JbpmTemplate有无参数的构造器,可以不使用构造器注入,只需要在spring配置文件中注它的jbpmConfiguration属性就可以了。

 

另,没有添加参考文章里说的过滤器,暂时没发现问题。



接触JBPM始于两年多前,当时还在广州一个公司实习,公司打算研发ITIL相关的项目,于是就开始知道了工作流,也就开始接触了JBPM一,SpringModules与JBPM的集成 
 

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:jee="http://www.springframework.org/schema/jee"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
  6.             http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">  
  7.     <!-- framework's contexts -->  
  8.   
  9.     <bean id="resource.PropertyConfigurer"  
  10.         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  11.         <property name="locations">  
  12.             <list>  
  13.                 <value>classpath:jdbc.properties</value>  
  14.             </list>  
  15.         </property>  
  16.     </bean>  
  17.   
  18.   
  19.   
  20.     <!-- JNDI DataSource for J2EE environments -->  
  21.     <!--jee:jndi-lookup id="dataSource" jndi-name="java:/comp/env/jdbc/moss" /-->  
  22.     <bean id="resource.DataSource"  
  23.         class="org.apache.commons.dbcp.BasicDataSource"  
  24.         destroy-method="close">  
  25.         <property name="driverClassName"  
  26.             value="${appserver.jdbc.driverClassName}" />  
  27.         <property name="url" value="${appserver.jdbc.url}" />  
  28.         <property name="username" value="${appserver.jdbc.username}" />  
  29.         <property name="password" value="${appserver.jdbc.password}" />  
  30.         <property name="maxActive" value="${appserver.jdbc.maxActive}" />  
  31.         <property name="maxIdle" value="${appserver.jdbc.maxIdle}" />  
  32.         <property name="maxWait" value="${appserver.jdbc.maxWait}" />  
  33.         <property name="defaultAutoCommit"  
  34.             value="${appserver.jdbc.defaultAutoCommit}" />  
  35.         <property name="removeAbandoned"  
  36.             value="${appserver.jdbc.removeAbandoned}" />  
  37.         <property name="removeAbandonedTimeout"  
  38.             value="${appserver.jdbc.removeAbandonedTimeout}" />  
  39.     </bean>  
  40.   
  41.   
  42.   
  43.     <!-- Hibernate SessionFactory -->  
  44.     <bean id="resource.SessionFactory"  
  45.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  46.         <property name="dataSource" ref="resource.DataSource" />  
  47.         <property name="configLocations">  
  48.             <list>  
  49.                 <value>classpath*:hibernate.cfg.xml</value>  
  50.             </list>  
  51.         </property>  
  52.     </bean>  
  53.        
  54.     <!-- jBPM configuration -->  
  55.     <bean id="resource.JbpmConfiguration"  
  56.         class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">  
  57.         <property name="configuration" value="classpath:jbpm.cfg.xml" />  
  58.         <property name="createSchema" value="false" />  
  59.         <property name="sessionFactory">  
  60.           <ref local="resource.SessionFactory"/>  
  61.         </property>  
  62.     </bean>  
  63.        
  64.     <!-- jBPM template -->  
  65.     <bean id="resource.JbpmTemplate"  
  66.         class="org.springmodules.workflow.jbpm31.JbpmTemplate">  
  67.         <constructor-arg index="0" ref="resource.JbpmConfiguration" />  
  68.     </bean>  
  69.   
  70. </beans>  

 

LocalJbpmConfigurationFactoryBean

最重要的就是LocalJbpmConfigurationFactoryBean了,相信Spring的用户对这样的Bean都很熟悉。根据jbpmConfiguration配置文件和提供的sessionFactory,它会创建一个可以与提供的流程定义协同工作的jBPM Configuration。sessionFactory属性可有可无,如果提供了,将会使用sessionFactory提供的session进行数据库操作。但是如果注入了sessionFactory,就可以重用Spring提供的事务管理架构,且不需要对jBPM做任何代码修改,还可以结合使用OpenSessionInView模式,好处显而易见吧。


JbpmTemplate and JbpmCallback

像Spring与Hibernate,JDBC的集成有相应的Template, Callback类一样,Spring与Jbpm的集成也有JbpmTemplate和JbpmCallback,且默认提供了一些便利方法供用户使用,例如findProcessInstance,findPooledTaskInstances,saveProcessInstance,signal等。

因为JbpmTemplate继承了JbpmAccessor,父类JbpmAccessor实现了InitializingBean,所以Spring在初始化这个JbpmTemplate时会调用afterPropertiesSet方法来配置JbpmTemplate所使用到的HibernateTemplate。JbpmAccessor 还做了一些访问异常的转换操作。



这两个类协同起来要完成的事情是,如果提供了SessionFactory或者
HibernateTemplate, 在JbpmCallback里的doInJbpm方法之前注入SessionFactory提供的hibernate session。如果没有提供SessionFactory,那么持久化的操作还是交回给Jbpm。如果存在SessionFactory, session的打开,关闭就由SessionFactory管理。否则由JBPM自身的持久化逻辑来维护。
这部分逻辑可以查看HibernateTemplate的execute方法:

Java代码
  1. public Object execute(final JbpmCallback callback) {   
  2.         final JbpmContext context = getContext();   
  3.   
  4.         try {   
  5.             // use the hibernateTemplate is present and if needed   
  6.             if (hibernateTemplate != null && hasPersistenceService) {   
  7.   
  8.                 // use hibernate template   
  9.                 return hibernateTemplate.execute(new HibernateCallback() {   
  10.                     /**  
  11.                      * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)  
  12.                      */  
  13.                     public Object doInHibernate(Session session) throws HibernateException, SQLException {   
  14.                         // inject the session in the context   
  15.                         context.setSession(session);   
  16.                         return callback.doInJbpm(context);   
  17.                     }   
  18.                 });   
  19.             }   
  20.   
  21.             // plain callback invocation (no template w/ persistence)   
  22.             return callback.doInJbpm(context);   
  23.   
  24.         }   
  25.         catch (JbpmException ex) {   
  26.             throw convertJbpmException(ex);   
  27.         }   
  28.         finally {   
  29.             releaseContext(context);   
  30.         }   
  31.   
  32.     }  
,但是对比过不同的工作流,还是觉得JBPM有前途,因为它隶属于JBOSS,社区活跃。当然,和其他JBOSS项目一样缺乏足够的支持,最有用的就是附带的User Guide Reference。


现在受Spring影响太深了,接触什么项目想到的首先就是尝试和Spring集成。接触JBPM也不例外,不过与JBPM和Spring的集成,已经有人做了,这个项目就是SpringModules-jbpm了,而且做的很优雅,充分体现了Spring提倡的Inversion of Control的美。


我尝试将这种美表述出来与大家分享,首先我会摘取Spring Modules手册里与JBPM集成的部分内容。跟着会引用一部分JBPM的手册里的相关章节和阅读一部分相关代码分析SpringModules集成的原理。最后谈一谈JBPM持久化与Spring事务管理的集成。相信能够让困惑于LazyLoading的朋友一些有益的启示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值