Spring, Springmodules, JBPM持久化集成理解系列一
【本系列如需转载,请注明作者及出处】
本系列文章假设阅者具备以下知识:
1,ThreadLocal相关知识
2,Spring持久化,事务管理相关知识
3,Hibernate 持久化相关知识
4,Jbpm 持久化相关知识
5,Springmodules项目相关知识
6,相关J2EE知识
且具备以下材料:
1,Spring源代码
2,Hibernate源代码
3,Jbpm源代码
4,Springmodules源代码
接触JBPM始于两年多前,当时还在广州一个公司实习,公司打算研发ITIL相关的项目,于是就开始知道了工作流,也就开始接触了JBPM,但是对比过不同的工作流,还是觉得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的朋友一些有益的启示。
一,SpringModules与JBPM的集成
<?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:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<!-- framework's contexts -->
<bean id="resource.PropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<!-- JNDI DataSource for J2EE environments -->
<!--jee:jndi-lookup id="dataSource" jndi-name="java:/comp/env/jdbc/moss" /-->
<bean id="resource.DataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="${appserver.jdbc.driverClassName}" />
<property name="url" value="${appserver.jdbc.url}" />
<property name="username" value="${appserver.jdbc.username}" />
<property name="password" value="${appserver.jdbc.password}" />
<property name="maxActive" value="${appserver.jdbc.maxActive}" />
<property name="maxIdle" value="${appserver.jdbc.maxIdle}" />
<property name="maxWait" value="${appserver.jdbc.maxWait}" />
<property name="defaultAutoCommit"
value="${appserver.jdbc.defaultAutoCommit}" />
<property name="removeAbandoned"
value="${appserver.jdbc.removeAbandoned}" />
<property name="removeAbandonedTimeout"
value="${appserver.jdbc.removeAbandonedTimeout}" />
</bean>
<!-- Hibernate SessionFactory -->
<bean id="resource.SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="resource.DataSource" />
<property name="configLocations">
<list>
<value>classpath*:hibernate.cfg.xml</value>
</list>
</property>
</bean>
<!-- jBPM configuration -->
<bean id="resource.JbpmConfiguration"
class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
<property name="configuration" value="classpath:jbpm.cfg.xml" />
<property name="createSchema" value="false" />
<property name="sessionFactory">
<ref local="resource.SessionFactory"/>
</property>
</bean>
<!-- jBPM template -->
<bean id="resource.JbpmTemplate"
class="org.springmodules.workflow.jbpm31.JbpmTemplate">
<constructor-arg index="0" ref="resource.JbpmConfiguration" />
</bean>
</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方法:
public Object execute(final JbpmCallback callback) {
final JbpmContext context = getContext();
try {
// use the hibernateTemplate is present and if needed
if (hibernateTemplate != null && hasPersistenceService) {
// use hibernate template
return hibernateTemplate.execute(new HibernateCallback() {
/**
* @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
*/
public Object doInHibernate(Session session) throws HibernateException, SQLException {
// inject the session in the context
context.setSession(session);
return callback.doInJbpm(context);
}
});
}
// plain callback invocation (no template w/ persistence)
return callback.doInJbpm(context);
}
catch (JbpmException ex) {
throw convertJbpmException(ex);
}
finally {
releaseContext(context);
}
}
分享到:
相关推荐
此外,还可以了解到如何将jbPM集成到Spring框架中,以及如何利用jbPM提供的API进行更复杂的流程控制,例如流程分支、并行任务和回调函数等。对于想要深入了解和应用jbPM的企业级开发人员来说,这是一个非常有价值的...
3. **Hibernate或JPA支持**:jbpm可以使用Hibernate作为持久化层,因此需要相应的`hibernate-core`或JPA实现(如`hibernate-entitymanager`)。如果项目已经使用Hibernate,只需确保版本兼容即可。 4. **其他依赖**...
jbpm 3.2.1还提供了事件处理机制,可以捕获流程中的特定事件,如任务完成、异常发生等,从而触发相应的回调或补偿逻辑。此外,它还包括了持久化机制,确保流程实例和相关数据在系统重启后能够恢复。 对于开发者来说...
8. **持久化与历史记录**:jbpm使用JPA进行数据持久化,了解如何配置数据库连接,并查看流程实例的历史记录,用于审计和分析。 9. **调试与测试**:学习使用jbpm的调试工具,进行流程实例的跟踪和调试,确保流程按...
5. **任务监听和回调**:Spring AOP可以用来创建拦截器或切面,监听工作流事件,例如任务分配、完成或超时,然后执行相应的业务逻辑。 6. **用户界面**:项目可能包含一个简单的Web界面,用户可以通过它来查看和...
4. **持久化**:jBPM使用Hibernate作为默认的持久化框架,存储流程实例和相关数据。理解实体类如ProcessInstance、NodeInstance和VariableInstance是如何映射到数据库的。 5. **工作流监听器**:允许自定义事件处理...