首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

OSWorkflow 入門實戰:配置詳解、MySQL 持久化、工作流定義與 Java API 調用

     編輯:Java 相關知識

OSWorkflow 核心架構

OSWorkflow 是 OpenSymphony 提供的輕量級工作流引擎,核心組件:

  • Workflow Engine:狀態機執行器
  • Persistence SPI:可插拔持久化 (JDBC/Hibernate/內存)
  • XML 配置:工作流定義、持久化映射、用戶集成
  • PropertySet:動態屬性存儲 (上下文變量)

MySQL 持久化配置詳解 (osworkflow.xml)


<osworkflow>
  <persistence class="com.opensymphony.workflow.spi.jdbc.MySQLWorkflowStore">
    <property key="datasource" value="jdbc/DefaultDS"/>
    
    <!-- 序列生成策略 (MySQL 自增模擬) -->
    <property key="step.sequence.increment" 
              value="INSERT INTO OS_STEPIDS (ID) values (null)"/>
    <property key="step.sequence.retrieve" 
              value="SELECT count(ID) FROM OS_STEPIDS"/>
    <property key="entry.sequence.increment" 
              value="INSERT INTO OS_ENTRYIDS (ID) values (null)"/>
    <property key="entry.sequence.retrieve" 
              value="SELECT count(ID) FROM OS_ENTRYIDS"/>
    
    <!-- 表/列映射 (必須與數據庫結構完全一致) -->
    <property key="entry.table" value="OS_WFENTRY"/>
    <property key="entry.id" value="ID"/>
    <property key="entry.name" value="NAME"/>
    <property key="entry.state" value="STATE"/>
    
    <property key="history.table" value="OS_HISTORYSTEP"/>
    <property key="current.table" value="OS_CURRENTSTEP"/>
    <property key="historyPrev.table" value="OS_HISTORYSTEP_PREV"/>
    <property key="currentPrev.table" value="OS_CURRENTSTEP_PREV"/>
    
    <property key="step.id" value="ID"/>
    <property key="step.entryId" value="ENTRY_ID"/>
    <property key="step.stepId" value="STEP_ID"/>
    <property key="step.actionId" value="ACTION_ID"/>
    <property key="step.owner" value="OWNER"/>
    <property key="step.caller" value="CALLER"/>
    <property key="step.startDate" value="START_DATE"/>
    <property key="step.finishDate" value="FINISH_DATE"/>
    <property key="step.dueDate" value="DUE_DATE"/>
    <property key="step.status" value="STATUS"/>
    <property key="step.previousId" value="PREVIOUS_ID"/>
  </persistence>
  
  <factory class="com.opensymphony.workflow.loader.XMLWorkflowFactory">
    <property key="resource" value="workflows.xml"/>
  </factory>
</osworkflow>

關鍵表結構 (ER 圖核心)

  • OS_WFENTRY:工作流實例主表 (ID, NAME, STATE)
  • OS_CURRENTSTEP:當前活動步驟 (ENTRY_ID, STEP_ID, ACTION_ID, OWNER, CALLER, STATUS...)
  • OS_HISTORYSTEP:歷史步驟審計軌跡 (同結構)
  • OS_CURRENTSTEP_PREV / HISTORYSTEP_PREV:步驟轉移關係 (PREVIOUS_ID → ID)
  • OS_STEPIDS / OS_ENTRYIDS:序列生成輔助表 (MySQL 無序列對象時的變通)
  • OS_PROPERTYENTRY:動態屬性存儲 (GLOBAL_KEY, ITEM_KEY, ITEM_TYPE, STRING_VALUE...)

PropertySet 配置 (propertyset.xml)


<propertysets>
  <propertyset name="jdbc" 
      class="com.opensymphony.module.propertyset.database.JDBCPropertySet">
    <arg name="datasource" value="java:comp/env/jdbc/DefaultDS"/>
    <arg name="table.name" value="OS_PROPERTYENTRY"/>
    <arg name="col.globalKey" value="GLOBAL_KEY"/>
    <arg name="col.itemKey" value="ITEM_KEY"/>
    <arg name="col.itemType" value="ITEM_TYPE"/>
    <arg name="col.string" value="STRING_VALUE"/>
    <arg name="col.date" value="DATE_VALUE"/>
    <arg name="col.data" value="DATA_VALUE"/>
    <arg name="col.float" value="FLOAT_VALUE"/>
    <arg name="col.number" value="NUMBER_VALUE"/>
  </propertyset>
</propertysets>

工作流註冊 (workflows.xml)


<workflows>
  <workflow name="leave" type="resource" location="leave.xml"/>
</workflows>

用戶集成配置 (osuser.xml)


<opensymphony-user>
  <provider class="com.opensymphony.user.provider.jdbc.JDBCAccessProvider">
    <property name="user.table">os_user</property>
    <property name="group.table">os_group</property>
    <property name="membership.table">os_membership</property>
    <property name="user.name">username</property>
    <property name="user.password">passwordhash</property>
    <property name="group.name">groupname</property>
    <property name="membership.userName">username</property>
    <property name="membership.groupName">groupname</property>
    <property name="datasource">java:comp/env/jdbc/DefaultDS</property>
  </provider>
  <!-- CredentialsProvider / ProfileProvider 同樣配置 -->
  <authenticator class="com.opensymphony.user.authenticator.SmartAuthenticator"/>
</opensymphony-user>

請假流程定義 (leave.xml) 核心元素解析


<workflow>
  <initial-actions>
    <action id="1" name="提交申請">
      <pre-functions>
        <function type="class">
          <arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
        </function>
      </pre-functions>
      <results>
        <unconditional-result old-status=" " status="申請中" step="1" owner="${caller}"/>
      </results>
    </action>
  </initial-actions>
  
  <steps>
    <step id="1" name="申請中">
      <actions>
        <action id="2" name="批准">
          <results>
            <unconditional-result old-status="申請中" status="已批准" step="-1" owner="${caller}"/>
          </results>
        </action>
        <action id="3" name="駁回">
          <results>
            <unconditional-result old-status="申請中" status="已駁回" step="-1" owner="${caller}"/>
          </results>
        </action>
      </actions>
    </step>
  </steps>
</workflow>

核心概念映射

XML 元素業務含義關鍵屬性
initial-actions流程啟動入口,至少一個id 唯一標識
action導致狀態流轉的動作id 全局唯一、name 顯示名
step流程節點/狀態位置 (非動作)id、name
result動作執行後的結果conditional-result (條件) / unconditional-result (默認)
status動作執行時的流程狀態
old-status動作執行後的新狀態
caller調用者 (當前用戶),預函數 Caller 自動注入記錄於 OS_HISTORYSTEP.CALLER
pre-functions動作執行前邏輯 (如權限檢查、變量準備)
post-functions動作執行後邏輯 (如發送通知、更新業務表)

Java API 調用實戰


public class LeaveWFBO {
    // 啟動流程:提交申請
    public long send(String employee) {
        Workflow workflow = new BasicWorkflow("peidw"); // caller = 員工ID
        workflow.setConfiguration(new DefaultConfiguration());
        long workflowId = -1;
        try {
            workflowId = workflow.initialize("leave", 0, null); // 初始化流程實例
            workflow.doAction(workflowId, 1, null);             // 執行 action 1 (提交)
        } catch (Exception e) { e.printStackTrace(); }
        return workflowId; // 返回流程實例 ID
    }
    
    // 處理審批:批准/駁回
    public void allow(long workflowId, int actionId) { // actionId: 2=批准, 3=駁回
        Workflow workflow = new BasicWorkflow("peidw");
        workflow.setConfiguration(new DefaultConfiguration());
        try {
            workflow.doAction(workflowId, actionId, null);
        } catch (Exception e) { e.printStackTrace(); }
    }
}

關鍵調用鏈

  1. new BasicWorkflow(caller):創建引擎實例,綁定調用者身份
  2. workflow.initialize("leave", 0, null):按名稱創建流程實例,返回 workflowId (OS_WFENTRY.ID)
  3. workflow.doAction(wfId, actionId, transientVars):執行指定動作,推進流程
  4. transientVars (Map) 傳遞臨時變量,供條件判斷/函數使用

調試與避坑經驗 (MySQL 5.0 實測)

  1. 序列表數據初始化:OS_STEPIDS/OS_ENTRYIDS 必須預先插入至少一行 (INSERT INTO OS_STEPIDS VALUES (0)),否則 SELECT count(ID) 返回 0 導致 ID 衝突
  2. 表名大小寫敏感:MySQL Linux 下表名區分大小寫,配置文件 value 必須與建表語句完全一致
  3. Caller 預函數必須配置:否則 ${caller} 變量無法解析,導致 owner 為空
  4. Datasource JNDI 名稱:java:comp/env/jdbc/DefaultDS (Web 容器) vs jdbc/DefaultDS (獨立應用),需區分環境
  5. 事務邊界:OSWorkflow 不管理事務,需外層 (Spring/EJB) 控制事務,確保流程變更與業務數據原子性

總結

OSWorkflow 以XML 定義流程、可插拔持久化、輕量級 API 為特點,適合中小型業務流程自動化。核心掌握點:

  1. 持久化配置與數據庫結構**嚴格對應** (含序列表技巧)
  2. 流程定義中 step (狀態位置) 與 action (流轉動作) 的區別
  3. result 類型:條件 vs 無條件,old-status/status 驅動狀態機
  4. Caller 預函數注入調用者,實現審批人記錄
  5. Java API 三步走:initialize → doAction → query
  6. 生產環境**必須**外層事務管理 (Spring @Transactional / EJB CMT)

通過 MySQL 實戰驗證的完整配置集,可直接作為項目啟動模板。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved