最近刚开始学习JBPM4.4,安装和运行其自带的例子均没有碰到什么问题。
但是,和项目整合的时候需要与原有的系统进行整合。所以,问题来了:
1、JBPM4.4到底需要哪些JAR包,jar包冲突了怎么办呢?
2、JPBM4.4怎么和原有的Spring配置整合在一起呢?
首先,第一个问题一直都是很困扰JAVA开发者的一个问题(jar包的依赖关系,版本冲突等等问题)。我认为有两种无奈的解决思路: 1、不管三七二十一,把所需的jar包一股脑的扔进去,等发生冲突了,再一个个剔除。2、不管这个框架需要什么jar包,直接运行你写的单元测试例子,查看出错信息一个个去将缺少的包加入进来。幸运的是我们原来的项目采用maven管理项目,所以我采用第二种思路,很轻松的就将jbpm4.4所需的最小依赖包加入进来了。
那么,接下来就是和spring的配置问题了。我查看了JPBM4.4的官方开发者指南(http://docs.jboss.com/jbpm/v4/devguide/html_single/)的第17节(Chapter 17. Spring Integration)中spring的配置描述 :
第一步骤(配置spring的事务管理):
The easiest way to integrate Spring with jBPM is to import the jbpm.tx.spring.cfg.xml in your jbpm.cfg.xml file:(最最简单的方法就是,直接在jbpm.cfg.xml文件中导入jbpm.tx.spring.cfg.xml)
<import resource="jbpm.tx.spring.cfg.xml" />
第二步骤(生成ProcessEngine对象,有了这个我们就可以操纵整个JBPM引擎了):
<bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper">
<property name="jbpmCfg" value="org/jbpm/spring/jbpm.cfg.xml"></property>
</bean>
<bean id="processEngine" factory-bean="springHelper" factory-method="createProcessEngine" />
这样我就配置好了吗?如果我们运行自己的单元测试,会发现真的配置可以运行。
第二步骤没什么难理解的就是spring的DI(依赖注入)生成ProcessEngine对象而已。第一步骤却是有点让人迷惑。为什么在jbpm.cfg.xml中引入一个jbpm.tx.spring.cfg.xml文件就可以使用到事务管理呢?平常我们配置的不都是要指定事务拦截器,并指定要拦截的方法吗?
好吧,那就看看jbpm.tx.spring.cfg.xml中到底干了些什么吧。我在jbpm-pvm-4.4.jar包中发现了该文件
<jbpm-configuration spring="enabled">
<process-engine-context>
<command-service name="newTxRequiredCommandService">
<retry-interceptor />
<environment-interceptor policy="requiresNew" />
<spring-transaction-interceptor policy="requiresNew" />
</command-service>
<!-- Default command service has a Spring transaction interceptor-->
<command-service name="txRequiredCommandService">
<retry-interceptor />
<environment-interceptor />
<spring-transaction-interceptor />
</command-service>
</process-engine-context>
<transaction-context>
<transaction type="spring" />
<hibernate-session current="true" />
</transaction-context>
</jbpm-configuration>
从xml标签的字面意思可以猜测<transaction-context>内的属性配置了使用spring事务拦截器。在<command-service>标签中的<spring-transaction-interceptor /> 应该就是要指定的spring事务拦截器了。但是,这个spring-transaction-interceptor什么都没指定,怎么知道到底要用我们项目中的哪个事务管理器呢?(这个问题确实挺让我困扰的。只怪了当时只看了最简单的配置,能跑起来就不了了之了。) 好吧,那就继续去官方手册找找吧。我发现了一行话:The spring-transaction-interceptor will look by default for a PlatformTransactionManager implementation by doing a search by type on the defined beans.(这个spring拦截器默认根据类型(by type)查找实现了PlatformTransactionManager接口的Bean并注入进来了。)而刚好我在项目中只配置了一个org.springframework.orm.hibernate3.HibernateTransactionManager的事务管理bean。而这个bean又是一个AbstractPlatformTransactionManager的实现类。所以。。。给它用by type的形式神不知鬼不觉的注入进来了。(一开始学习的时候觉得配置的方式蛮好的,有的时候找问题,配置的东西真的给人调试,查找带来太大的麻烦,该死的XML,该死的配置,发个牢骚O(∩_∩)O哈哈~)。
那还有一个问题:如果我们项目中配置了多个事务管理器,那spring事务拦截倒是用的是哪个事务管理器呢?我们如果想指定的话应该怎么指定呢?
为了查看多个事务管理器的情况下到底用哪个,我写了两个测试事务管理类,都继承org.springframework.orm.hibernate3.HibernateTransactionManager并重写了doCommit方法,在该方法中添加一行日志信息(比如:我调用了事务管理器1(或2))。并在配置文件中配置了这两个事务管理bean。经单元测试例子运行后查看日志得知:默认使用第一个实例化的事务管理bean。
如果想使用其他个事务管理的话,可以指定的。怎么指定,官方指南也写了。只要指定transaction-manager即可。
<spring-transaction-interceptor transaction-manager="你的事务管理器" />