jbpm4.2与spring整合(2009-11-22 00:50:14)标签:jbpm4.2 spring it

来源:互联网 发布:淘宝视觉设计规范 编辑:程序博客网 时间:2024/05/09 21:57
jbpm4.2与spring整合(2009-11-22 00:50:14)

最近研究工作流,用到了jbpm这个开源的东西.用起来感觉还不错,后来在与spring整合的时候,出现了许多问题,好在经过研究与摸索,将问题一一解决.现在把jbpm与spring整合用到的一些配置文件与代码发上来,供需要这方面资料的朋友参考.

首先是一些必要的配置文件:

-------------------------jbpm.cfg.xml---------------------------

<?xml version="1.0" encoding="UTF-8"?>

<jbpm-configuration>

 <process-engine-context>
    <repository-service />
    <repository-cache />
    <execution-service />
    <history-service />
    <management-service />
    <task-service />
    <identity-service />
    <command-service name="txRequiredCommandService">
      <retry-interceptor />
      <environment-interceptor />
      <spring-transaction-interceptor/>
    </command-service>
   
    <hibernate-configuration>
      <cfg resource="jbpm.hibernate.cfg.xml" />    
    </hibernate-configuration>

    <object class="org.jbpm.pvm.internal.id.DatabaseDbidGenerator">
      <field name="commandService"><ref object="txRequiredCommandService" /></field>
    </object>

    <object class="org.jbpm.pvm.internal.id.DatabaseIdComposer" init="eager" />

    <deployer-manager>
      <jpdl-deployer />
    </deployer-manager>
   
    <script-manager default-expression_r_r-language="juel"
                    default-script-language="juel"
                    read-contexts="execution, environment, process-engine"
                    write-context="">
        <script-language name="juel" factory="org.jbpm.pvm.internal.script.JuelScriptEngineFactory" />
    </script-manager>
    <job-executor auto-start="false" />
    <types resource="jbpm.variable.types.xml" />
  </process-engine-context>

 

 <transaction-context>
  <repository-session />
  <db-session />
  <message-session />
  <timer-session />
  <history-session />
  <mail-session>
   <mail-server>
    <session-properties resource="jbpm.mail.properties" />
   </mail-server>
  </mail-session>

  <!-- Need to set explicitly that we don't want jbpm to create sessions -->
  <hibernate-session current="true" />
 </transaction-context>
</jbpm-configuration>

-----------------------------jbpm.cfg.xml结束-------------------------

 

然后是hibernate.cfg.xml

-----------------------------hibrnate.cfg.xml-------------------------

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory name="jbpm4-spring">
  <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
 </session-factory>
</hibernate-configuration>
----------------------------hibernate.cfg.xml结束-----------------

接下来是spring的配置文件,applicationContext.xml.我按功能不同将其细分为四个文件:

applicationContext-dao.xml 数据库配置信息

applicationContext-process.xml jbpm需要用到的一些配置信息

applicationContext-service.xml 程序中用到的一些服务类的定义,在这个文件中注入

applicationContext-common.xml 其它配置

 

---------------------applicationContext-dao.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"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.hbm2ddl.auto">none</prop>
   </props>
  </property>
  <property name="configLocation">
    <value>classpath:hibernate.cfg.xml</value>
   </property>
  <property name="mappingLocations">
   <list>
    <value>classpath:jbpm.execution.hbm.xml</value>
    <value>classpath:jbpm.repository.hbm.xml</value>
    <value>classpath:jbpm.task.hbm.xml</value>
    <value>classpath:jbpm.history.hbm.xml</value>
   </list>
  </property>
 </bean>
 <!--此处采用Oracle数据库,c3p0数据源-->
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
  <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:sys" />
  <property name="user" value="username" />
  <property name="password" value="password" />
 </bean>

</beans>

---------------------------applicationContext-dao.xml结束--------------------

 

---------------------------applicationContext-process.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"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">


 <bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration">
  <constructor-arg value="jbpm.cfg.xml" />
 </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" />
 <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>  
    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>  
    <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/> 
</beans>

--------------------------applicationContext-process.xml结束--------------------

 

--------------------------applicationContext-service.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="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!--类中需要的jbpm对象的注入-->

 <bean id="simpleProcessService" class="com.sinosoft.simpleflow.SimpleProcessServiceImpl">
  <property name="processEngine" ref="processEngine" />
  <property name="repositoryService" ref="repositoryService" />
  <property name="executionService" ref="executionService" />
  <property name="identityService" ref="identityService" />
  <property name="historyService" ref="historyService" />
  <property name="taskService" ref="taskService" />  
 </bean>
 ----------------------applicationContext-service.xml结束----------------------

-----------------------applicationContext-common.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"
 xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">


    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
         <list>
             <value>classpath:/log4j.properties</value>
            </list>
        </property>
    </bean>

 
 
</beans>

 


</beans>

-------------------------applicationContext-common.xml结束-----------------------

jbpm4.2与spring的配置都已完成,下面我们再看一下web.xml中是如何配置的

------------------------web.xml------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext*.xml</param-value>
    </context-param>

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
   
    <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

   
  <servlet>
    <description>This is the description of my WorkFlowServlet</description>
    <display-name>This is the display name of my WorkFlowServlet</display-name>
    <servlet-name>WorkFlowServlet</servlet-name>
    <servlet-class>com.sunzhe.simpleflow.WorkFlowServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>WorkFlowServlet</servlet-name>
    <url-pattern>/WorkFlowServlet</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
---------------------------web.xml结束----------------------

 

下面一切配置工作都已经完成,程序中需要用到如下代码.

----------------------SimpleProcessServiceImpl.java-----------------

private ProcessEngine processEngine = null;

private RepositoryService repositoryService = null;

private ExecutionService executionService = null;

public ProcessEngine getProcessEngine() {
  return processEngine;
 }
 public  void setProcessEngine(ProcessEngine processEngine) {
  SimpleProcessServiceImpl.processEngine = processEngine;
 }

public RepositoryService getRepositoryService() {
  return repositoryService;
 }
 public  void setRepositoryService(RepositoryService repositoryService) {
  SimpleProcessServiceImpl.repositoryService = repositoryService;
 }
 public ExecutionService getExecutionService() {
  return executionService;
 }
 public  void setExecutionService(ExecutionService executionService) {
  SimpleProcessServiceImpl.executionService = executionService;
 }

 

public static List<ProcessDefinition> getLatestProcessDefinition() throws ServletException, IOException {

  List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
      .orderAsc(ProcessDefinitionQuery.PROPERTY_NAME).list();
  
  Map<String,ProcessDefinition> map = new LinkedHashMap<String,ProcessDefinition>();
  for (ProcessDefinition pd : processDefinitions) {
   String key = pd.getKey();
   ProcessDefinition definition = map.get(key);
   if ((definition == null) || (definition.getVersion() < pd.getVersion())) {
    map.put(key, pd);
   }
  }
  return new ArrayList(map.values());
 }

--------------------------SimpleProcessServiceImpl.java结束------------------

    这样,在我们的action中,就可以调用服务类的getLatestProcessDefinition()方法,来得到已经发布的流程了.具体在使用中,每个人根据自己的理解与需要,代码都不相同,但是只要配置方法正确,那么程序中的代码也是大同小异.网上关于jbpm4.2的信息还很少,必竟是刚发布的产品,而我们在使用时,肯定会遇到各种问题.如果遇到运行时的异常或错误等,比如session关闭,事务配置不正确,找不到事务等等,在确定配置文件没有问题的情况下(如没有配置事务管理,或配置多个事务管理导致jbpm不知该使用哪个.等).那么就要仔细排查程序,看是否在初始化或调用过程中存在问题.在上面给出的程序代码中,我们使用spring注入的方式得到jbpm相关的对象,如果不用注入的方法,直接用processEngine = new Configuration().buildProcessEngine();也可以得到这些对象.在后台看到得到的对象并不是null.但是在使用中jbpm就会报错抛出异常.

    总之,通过多琢磨,多试,多研究.肯定会将jbpm4.2与spring整合成功.希望能与大家多交流有关jbpm工作流引擎的经验,文中如有错误,还请指正.