通过查找jbpm4.1的帮助文档和网络上无数的文章,今天终于完成了一个这方面的web Demo的编写,系统的环境是:jbpm4.1+spring2.5.3+hibernate3.2+struts2+jboss5.1
整合的过程中,一开始走了很多的弯路,(ˇˍˇ) 想不通过application server,用standalone的方式进行,因为作为jbpm4.1、spring2.5.2+hibernate3.2分别是可以通过standalone的方式运行的。当时想关键的问题是解决jta的问题,如果在standalone环境中搭建一个jta的环境,应当是可以实现的。于是利用jotm和jbossTS搭建了jta的环境,当把jbpm4.1和spring+hibernate放在一起启动时,无论怎么配置,系统都会报事物无法成功的错误,于是仔细的看了一下jbpm的配置文件,发现它的事物中不但有数据库的管理,还有jms、session、mail的管理,而现在的standalone的jta事物管理框架都是只支持database,很是郁闷,这条路走不通了。
只能通过application server来整合他们了!为了方便控制,也只好再加上一个技术框架struts了,并且application server需要支持jta,这样的服务器很多有jboss、WebSphere、WebLogic、sun application server等,tomcat是不行的。jboss用的比较多,于是选用了jboss的最新版本5.1,发现现在jboss的启动速度有了一定的提高,在Eclipse下面的调试方便多了。
在jbpm4.1的文档上(第16章),有一小段化很重要:
<bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration"> <constructor-arg value="be/inze/spring/demo/jbpm.cfg.xml" /> </bean>
The jBPM services can also be defined in the Spring applicationContext, as following:
<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" />
The previous section already showed how the jBPM services can be made accessible for other Spring services.
The other use case is calling Spring beans from within a process. This can be done by using an expression
which resolves to the name of a Spring bean.
<java name="echo" expr="#{echoService}" method="sayHello" > <transition name="to accept" to="join1"/> </java>
The scripting engine will look into all contexts from the bean named echoService. If you configured the ScriptManager as above, Spring will be the last context to search for. You can also add a Spring bean to the Spring Application context (eg IdentitySessionImpl with id identitySession ) and use it in the jBPM config (eg by adding <env class="identitySession" />)
提供了两个又用的信息:
一是可以通过SpringConfiguration配置,利用spring的配置文件象管理普通bean一样,来管理jbpm的各种service。
二是在这种配置下,jbpm中的process文件,通过expr的方式,可以直接访问spring中配置的bean。
可惜他没有提供例子的代码和完整的工程,否则学习起来就方便多了。
作为以上的工作以后,就是进行具体的配置了,我用的是一个很简单的流程文件:
<?xml version="1.0" encoding="UTF-8"?>
<process name="process" xmlns="http://jbpm.org/4.0/jpdl ">
<start name="start1" g="215,105,48,48">
<transition name="to java1" to="java1" g="-53,-17"/>
</start>
<java name="java1" expr="#{testService}" method="save" g="310,224,92,52">
<transition name="to end1" to="end1" g="-47,-17"/>
</java>
<end name="end1" g="499,170,48,48"/>
</process>
其中testService是在applicationContext文件中配置的bean:
<?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:context="http://www.springframework.org/schema/context "
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.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd ">
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:JbpmXADS</value></property>
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
<property name="jndiTemplate" value ="java:/UserTransaction" />
</bean>
<!--
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
-->
<aop:config proxy-target-class="true">
<aop:advisor pointcut="execution( * com.jbpm.test.web.TestAction.*(..))" advice-ref="txAdvice"/>
<aop:advisor pointcut = "execution( * org.jbpm.pvm.internal.repository.DeploymentImpl.deploy*(..))" advice-ref="jbpmAdvice"/>
</aop:config>
<tx:advice id="jbpmAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="deploy*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="deployJpdlFromClasspath*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="configLocation">
<value>WEB-INF/jbpm.hibernate.cfg.xml</value>
</property>
</bean>
<bean id = "testDao" class = "com.jbpm.test.spring.TestTableDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id = "testService" class = "com.jbpm.test.spring.TestBussiness">
<property name="dao" ref = "testDao"/>
</bean>
<bean id = "jbpmConfiguration" class = "org.jbpm.pvm.internal.cfg.SpringConfiguration">
<constructor-arg value = "jbpm.cfg.xml"></constructor-arg>
</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" />
</beans>
上面是整个spring applicationContext文件的内容。
其他的就是一些spring、hibernate、struts的常规配置内容了。
整体的项目内容见附件。
如果愿意讨论相关的话题,可以给我留言