1. 程式人生 > >將osworkflow與spring和hibernate整合的基本介紹

將osworkflow與spring和hibernate整合的基本介紹

1. 將osworkflow與spring和hibernate結合的原因

    1)簡化對osworkflow的配置

    2)利用hibernate框架的一些特性,如持久化,快取等

    3)事務管理,osworkflow本身是不支援事務的,而事務是作為一個產品的基本功能

    4)可以利用spring加入其它的擴充套件功能,如使用者認證和鑑權。這點本文沒有介紹。

2、準備

    下載osworkflow-2.8.0版本 ,下載hibernate-3.2版本,下載spring-framework-2.5.5版本

3、搭建eclipse環境

  測試的工程目錄如下:

src  原始碼目錄

   oswf  包路徑

       Test.java 測試類,後面會給出原始碼

bin  編譯目的目錄

    oswf 包路徑

         Test.class  編譯生成的class檔案

   //下面的幾個配置檔案位於bin目錄下

    log4j.properties 這是log4j的配置檔案,這可以不需要

    //下面三個hbm.xml檔案是osworkflow持久化的o/r對映檔案,這是從osworkflow的原始碼目錄com"opensymphony"workflow"spi"hibernate3下拷出來的。

    HibernateCurrentStep.hbm.xml

    HibernateHistoryStep.hbm.xml

    HibernateWorkflowEntry.hbm.xml

    //下面三個檔案直接從osworkflow自帶的例子中獲取的,其中example.xml是流程定義檔案。osuser.xml是osuser的配置檔案。workflows.xml是osworkflow配置有哪些流程定義的配置檔案。

    example.xml

    osuser.xml

    workflows.xml

osworkflow-spring.xml  //這是spring 的配置檔案,位於根目錄下,後面會給出原始碼

//下面兩個是eclipse的工程檔案

.project

.classpath

4、編寫spring 的beans.xml配置檔案

  檔名如osworkflow-spring.xml,內容如下:

<!-- 下面配置資料來源datasource,這裡用的是spring 自帶的一個測試用的連線池。也可以用開源的連線池Jakarta Commons DBCP。
如果程式是執行在servlet容器中,如tomcat中,可直接使用在tomcat中配置的資料庫連線池jdni。
這裡給出的是oracle資料庫驅動,可以換成任意的資料庫,如mysql等。 -->

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
    <property name="driverClassName">
        <value>oracle.jdbc.driver.OracleDriver</value>
    </property>
    <property name="url">
        <value>jdbc:oracle:thin:@127.0.0.1:1521:orcl</value>
    </property>
    <property name="username">
        <value>test</value>
    </property>
    <property name="password">
        <value>test</value>
    </property>
</bean>
    
<!-- 配置hibernate的sessionFactory以及相關的配置,這是使用hibernate的入口-->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource"><ref local="dataSource"/></property>
  <property name="mappingResources">
   <list>
    <value>HibernateCurrentStep.hbm.xml</value>
    <value>HibernateHistoryStep.hbm.xml</value>
    <value>HibernateWorkflowEntry.hbm.xml</value>    
   </list>
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</prop>
    <prop key="hibernate.current_session_context_class">thread</prop>
    <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
   </props>
  </property>
 </bean>

<!-- 配置osworkflow中所用的propertyset,這裡配置的是預設的記憶體方式的propertyset。-->
 <bean id="propertySetDelegate" class="com.opensymphony.workflow.util.PropertySetDelegateImpl"> 
 </bean>

<!-- 配置osworkflow的儲存工廠WorkflowStore -->
 <bean id="workflowStore" class="com.opensymphony.workflow.spi.hibernate3.SpringHibernateWorkflowStore">
  <property name="sessionFactory"><ref local="sessionFactory"/></property>
  <property name="propertySetDelegate"> <ref bean="propertySetDelegate"/> </property>
 </bean>

    <!-- 配置osworkflow的工廠類 -->
 <bean id="workflowFactory" class="com.opensymphony.workflow.spi.hibernate.SpringWorkflowFactory" init-method="init">
        <property name="resource"><value>workflows.xml</value></property>
        <property name="reload"><value>false</value></property>
 </bean>

 <bean id="osworkflowConfiguration" class="com.opensymphony.workflow.config.SpringConfiguration">
  <property name="store"><ref local="workflowStore"/></property>
  <property name="factory"><ref local="workflowFactory"/></property>  
 </bean>

   <!-- 配置osworkflow的工作流介面。注意下面的建構函式引數值test是使用者名稱 -->
 <bean id="workflowTarget" class="com.opensymphony.workflow.basic.BasicWorkflow">
  <constructor-arg><value>test</value></constructor-arg>
  <property name="configuration"><ref local="osworkflowConfiguration"/></property> 
 </bean>

    <!-- 下面的配置是配置讓oswrorkflow使用spring的事務框架 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
   <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!-- 應用程式在程式碼中唯一要關注的就只有這一個Bean,其它不用關注 -->
<bean id="workflow" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
 <property name="transactionManager" ref="transactionManager"/>
 <property name="target" ref="workflowTarget"/>

 <property name="transactionAttributes">
  <props>
   <prop key="*">PROPAGATION_REQUIRED</prop>
  </props>
 </property>
</bean>

</beans>

5、編寫測試程式碼,只有一個類,程式碼如下:

package oswf;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import com.opensymphony.user.Group;
import com.opensymphony.user.User;
import com.opensymphony.user.UserManager;
import com.opensymphony.workflow.Workflow;

public class Test {


 public static void main(String[] args) {
  
  try{
  UserManager um = UserManager.getInstance();
     User test = um.createUser("test");
     test.setPassword("test");

     Group foos = um.createGroup("foos");
     Group bars = um.createGroup("bars");
     Group bazs = um.createGroup("bazs");

     test.addToGroup(foos);
     test.addToGroup(bars);
     test.addToGroup(bazs);
  }
  catch(Exception e){
   System.out.println("create user error,app exit");
   return;
  }
  System.out.println("create user success");

  Resource res = new FileSystemResource("osworkflow-spring.xml");
  XmlBeanFactory beanFactory =new XmlBeanFactory(res);
  Workflow workflow = (Workflow) beanFactory.getBean("workflow"); 
  
  try { 
   workflow.initialize("example", 100, null); 
  } catch (Exception e) 
  { 
   e.printStackTrace(); 
  }
 }
}
程式碼是,首先要建立一個使用者(這裡使用的是osworkflow預設繫結的osuser框架)。然後獲取workflow  bean,再呼叫initialize方法建立一個新的流程。

6、問題

    1)osworkflow使用了propertyset框架,但propertyset框架和osworkflow都是opensymphony下的一個開源專案。osworkflow中提供的propertyset jar包不支援hibernate3,因此本例子中是使用記憶體化的propertyset,沒有持久化propertyset。

2)osworkflow中的BasicWorkflow類的建構函式必須提供一個引數,引數是osuser中的使用者。而且沒有提供設定使用者的set方法,這樣就只能在配置檔案中把使用者名稱寫死。這隻能用在測試環境中。在實際中需要修改這個程式碼,支援動態設定使用者。

3)osuser框架不支援通過hibernate持久化,如果要支援,需要自己下載原始碼改寫。但osuser支援通過jdbc持久化。