Spring+Mysql+Jbpm整合)

來源:互聯網
上載者:User
最近因為工作需要做一個工作流程相關的DEMO,研究了一下JBPM,記錄一下個人的心得與體會。

軟體環境:

    * spring2.0.2
    * hibernate3.2.2
    * spring modules 0.8 (Jbpm3.1)
    * jbpm3.1.4
    * struts2.0.6

配置

Spring Module Jbpm模組提供了幾個工具類用來整合spring和jbpm,關於具體的配置可以參見spring module下載包中的參考手冊,按照上面的指示來就OK了,這裡粘貼樣本配置。
xml 代碼

   1. <!--sp-->xml version="1.0" encoding="UTF-8"?>  
   2. <!--CTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"</sp-->>  
   3. <beans default-autowire="byName" default-lazy-init="true">  
   4.     <bean id="approveWorkflow"  
   5.         class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean">  
   6.         <property name="definitionLocation"  
   7.             value="classpath:jbpm/audit/processdefinition.xml" />  
   8.     bean>  
   9.     <bean id="jbpmConfiguration"  
  10.         class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">  
  11.         <property name="sessionFactory" ref="sessionFactory" />  
  12.         <property name="configuration" value="classpath:jbpm/jbpm.cfg.xml" />  
  13.         <property name="processDefinitions">  
  14.             <list>  
  15.                 <ref local="approveWorkflow" />  
  16.             list>  
  17.         property>  
  18.   
  19.     bean>  
  20.     <bean id="jbpmTemplate"  
  21.         class="org.springmodules.workflow.jbpm31.JbpmTemplate">  
  22.         <constructor-arg index="0" ref="jbpmConfiguration" />  
  23.         <constructor-arg index="1" ref="approveWorkflow" />  
  24.     bean>  
  25. beans>  
  26.   

比較關鍵的是為了能夠使JBPM實體和業務實體使用同一個會話工廠,這樣可以在JBPM流程執行個體中持久化業務實體物件。必須將業務實體映射和JBPM的實體映射進行整合。我的作法是改寫JBPM本身提供的hibernate.cfg.xml檔案,將業務實體包括在裡面。
xml 代碼

   1. <!--sp-->xml version='1.0' encoding='utf-8'?>  
   2.   
   3. <!--CTYPE hibernate-configuration PUBLIC   </sp-->
   4.           "-//Hibernate/Hibernate Configuration DTD 3.0//EN"   
   5.           "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
   6.   
   7. <hibernate-configuration>  
   8.   <session-factory>     
   9.   
  10.         <property name="hibernate.cache.use_second_level_cache">  
  11.             false   
  12.         property>         
  13.         <property name="hibernate.cache.use_query_cache">  
  14.             false   
  15.         property>  
  16.         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialectproperty>  
  17.         <property name="hibernate.show_sql">falseproperty>  
  18.         <property name="hibernate.query.factory_class">  
  19.             org.hibernate.hql.ast.ASTQueryTranslatorFactory   
  20.         property>  
  21.            
  22.            
  23.     <!--  下面是業務實體映射 -->   
  24.     <mapping resource="com/emap/jbpm/model/Apply.hbm.xml"/>  
  25.   
  26.     <!-- 下面是JBPM引擎本身的實體映射 -->  
  27.     <mapping resource="org/jbpm/graph/action/Script.hbm.xml"/>  
  28.   
  29.     <mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />  
  30.        
  31.     <!-- graph.def mapping files -->  
  32.     <mapping resource="org/jbpm/graph/def/ProcessDefinition.hbm.xml"/>  
  33.     <mapping resource="org/jbpm/graph/def/Node.hbm.xml"/>  
  34.     <mapping resource="org/jbpm/graph/def/Transition.hbm.xml"/>  
  35.     <mapping resource="org/jbpm/graph/def/Event.hbm.xml"/>  
  36.     <mapping resource="org/jbpm/graph/def/Action.hbm.xml"/>  
  37.     <mapping resource="org/jbpm/graph/def/SuperState.hbm.xml"/>  
  38.     <mapping resource="org/jbpm/graph/def/ExceptionHandler.hbm.xml"/>  
  39.     <mapping resource="org/jbpm/instantiation/Delegation.hbm.xml"/>  
  40.        
  41.     ........   
  42.        
  43.   session-factory>  
  44. hibernate-configuration>  

下面我們看看sessionFactory工廠的配置。
xml 代碼

   1. <!--sp-->xml version="1.0" encoding="UTF-8"?>  
   2. <!--CTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"</sp-->>  
   3. <beans default-autowire="byName" default-lazy-init="true">  
   4.   
   5.     <!-- 資料來源定義,使用Apache DBCP 串連池 -->  
   6.     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
   7.         <property name="driverClassName" value="${jdbc.driverClassName}"/>  
   8.         <property name="url" value="${jdbc.url}"/>  
   9.         <property name="username" value="${jdbc.username}"/>  
  10.         <property name="password" value="${jdbc.password}"/>  
  11.     bean>  
  12.        
  13.     <!-- Hibernate SessionFactory -->  
  14.     <bean id="sessionFactory"  
  15.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  16.         <property name="dataSource" ref="dataSource" />  
  17.         <property name="configLocations">  
  18.             <list>  
  19.                 <value>classpath:jbpm/hibernate.cfg.xmlvalue>  
  20.             list>  
  21.         property>  
  22.     bean>  
  23.     <!--Hibernate TransactionManager-->  
  24.     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  25.         <property name="sessionFactory" ref="sessionFactory"/>  
  26.     bean>  
  27. beans>  

遺留問題

如何使用JBPM Process Designer外掛程式?

       一直沒找到如何使用JBPM Process Designer外掛程式的使用文檔,比如如何配置JBPM安裝路徑,如何部署。目前唯一用到的功能就是編寫流程檔案。
如何發布流程檔案?

        對於如何發布流程檔案,我比較同意如下文章中的觀點,編程實現或許是最簡潔的方式。

www.pcdog.com/edu/java/2006/11/v171946.html
如何關聯業務實體和流程執行個體?

        JBPM主要用來管理商務程序,記錄每個流程進入哪個環節,同時還要儲存一些狀態,這些狀態資訊可能來自於業務實體。JBPM的實現方式是將這些狀態資訊序列化到資料庫的表列。

        假定有一個訂單處理的流程,現在要擷取某個角色當前的所有工作清單,同時將關聯的訂單資訊展示給使用者,我們應該如何處理?目前我想到有以下幾種方式:

        方式一:在構建任務執行個體的時候,將業務實體持久化到contextInstance,在擷取工作清單時從任務執行個體中直接解析出業務實體。如果需要儲存的業務實體資料量很大,這會給JBPM資料庫造成很大的資料冗餘。

        方式二:在構建任務執行個體的時候,僅將業務實體的唯一識別碼持久到contextInstance,在擷取工作清單時從任務執行個體中解析出任務實體的唯一識別碼,然後再根據此標識符查詢業務實體資料庫。這種情況會造成查詢一個包含N個的工作清單時,需要N+1次資料庫查詢,顯然效能是無法滿足需求的。

        方式三:是否可以在構建業務實體時,和TaskInstance進行關聯?這種方式會造成業務實體和JBPM緊耦合,而且必須對JBPM本身有比較深刻的理解。

        有什麼更好的辦法解決這種問題呢?個人以為方式一可能是目前性價比最好的解決方式吧。
一點體會

         JBPM看來在國內並沒有得到很多的應用,資料都比較稀缺,唯一的參考手冊也是非常的淺顯和簡單。而其源碼的注釋不是很好,這在國外的開源軟體中是很罕見的。

         JBPM提供的某些API不是很全,舉個例子,假定我要查詢某個角色某個時間段的所有工作清單。因為TaskMgmtSession僅提供了findXXXTaskInstances(String actorId)方法,所以我只能先查詢出該角色的所有工作清單,採用如下代碼:
java 代碼

   1. TaskMgmtSession taskMgmtSession = context.getTaskMgmtSession();   
   2.  List tasks = taskMgmtSession.findPooledTaskInstances(actorId);  

        然後再在記憶體中使用類似如下代碼進行過濾。
java 代碼

   1. if (task.getName().equals(taskName) && !task.hasEnded())  

這種方式太笨拙和低效了。

 

如果是發布流程到資料庫的話:

JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
//由 processdefinition.xml 產生相對應的流程定義類 ProcessDefinition
InputStream is = new FileInputStream(
"D:/oa/workflow/processes/PresaleHandlerForBusinessReport.xml");

ProcessDefinition processDefinition = ProcessDefinition.parseXmlInputStream(is);
try {
jbpmContext.deployProcessDefinition(processDefinition);

} catch (Exception e) {
e.printStackTrace();
} finally {
jbpmContext.close();
}

如果是卸載流程定義檔案的話:

JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

try {
jbpmContext.getGraphSession().deleteProcessDefinition(Long.parseLong("5"));
} catch (Exception e) {
e.printStackTrace();
} finally {
jbpmContext.close();
}

記得jbpmContext一定要關閉。這裡有個問題,假如你要刪除的那個流程被使用的過的話,當你再去卸載這個流程的時候,這個流程未必能刪除的了。 我有的時候會碰到這樣的情況。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.