1. 程式人生 > >工作流引擎activiti

工作流引擎activiti

一。activiti簡介

      Activiti專案是一項新的基於Apache許可的開源BPM平臺,從基礎開始構建,旨在提供支援新的BPMN 2.0標準,包括支援物件管理組(OMG),面對新技術的機遇,諸如互操作性和雲架構,提供技術實現。
       創始人Tom Baeyens是JBoss jBPM的專案架構師,以及另一位架構師Joram Barrez,一起加入到建立Alfresco這項首次實現Apache開源許可的BPMN 2.0引擎開發中來。

       Activiti是一個獨立運作和經營的開源專案品牌,並將獨立於Alfresco開源ECM系統執行。 Activiti將是一種輕量級,可嵌入的BPM引擎,而且還設計適用於可擴充套件的雲架構。 Activiti將提供寬鬆的Apache許可2.0,以便這個專案可以廣泛被使用,同時促進Activiti BPM引擎和BPMN 2.0的匹配,該專案現正由OMG通過標準審定。 加入Alfresco Activiti專案的是VMware的SpringSource分支,Alfresco的計劃把該專案提交給Apache基礎架構,希望吸引更多方面的BPM專家和促進BPM的創新。

    Activiti框架用於定義業務邏輯相關的流程 ,開啟相關流程例項,流程變數控制流程走向,使用者及組完成流程任務

Activiti流程定義使用bpmn2.0標準 該標準通過xml定義了所有業務流程相關的節點 比如 開始 結束 使用者任務 排他路由 並行路由等 由於編寫xml比較困難 activiti提供了eclipse相關外掛 通過繪圖方式來生成xml

相關網站:
官網:https://www.activiti.org/
使用者嚮導:https://www.activiti.org/userguide
中文使用者嚮導:http://www.mossle.com/docs/activiti/index.html

eclipse外掛安裝

(參考使用者嚮導https://www.activiti.org/userguide/#activitiDesigner)
eclipse點選選單  Help → Install New Software
輸入以下資訊:
  Name:Activiti BPMN 2.0 designer
  Location:http://activiti.org/designer/update/

點選ok 後選擇同意協議後安裝完成即可 新建任意專案 新建diagram檔案 操作如下gif動態圖

相關概念解釋

  •  流程引擎:流程定義和流程例項相關的入口api 流程引擎可以生成資料庫的儲存表 通過產生不同的service來操作不同的流程  
  1. repositoryService 用於釋出流程定義  
  2. taskService用於操作任務 (任務查詢,任務完成,設定流程變數)
  3. runtimeService可以用於操作流程例項 (執行流程,設定流程變數) 
  4. historyService可以檢視歷史流程
  5. IdentityService 操作使用者和組資訊

    以下程式碼就是流程引擎以及各服務的相關程式碼

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    TaskService taskService = processEngine.getTaskService();
    ManagementService managementService = processEngine.getManagementService();
    IdentityService identityService = processEngine.getIdentityService();
    HistoryService historyService = processEngine.getHistoryService();
    FormService formService = processEngine.getFormService();
    DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();
  •   流程定義:將bpmn相關的檔案和圖片釋出到流程資料庫中 生成對應的流程資訊 流程經過哪些任務 指派給哪個使用者完成任務
  •   流程例項 : 每個定義都可以產生多個流程例項 流程例項所有的任務需要指派的使用者去完成後才能走向下一個節點,存在多個分支的使用者節點需要通過流程變數值來判斷流程走向
bpmn圖中相關節點解釋(常用)

開始節點 所有的流程圖都需要有個開始節點

  結束節點 所有流程圖都必須有個結束節點
   任務節點 需要使用者處理的任務 比如審批就是需要人工去完成的一個任務 就需要定義任務節點 該節點被普遍
                     使用
順序線 上一個節點完成後 需要走到的下一個節點可以通過 順序線連線

 排他節點 流程需要分支需要通過排他節點 進行判斷 如果有多個分支 最後流程只會走向其中一個分支

                     比如請假  天數<3天 走組長審批  3-5天 走專案經理審批  5天以上boss審批 最後請假了多少天 只會是某個人審批 
                     具有排他性 

 並行節點 比如有兩個分支  有可能兩個分支流程都需要走  可以使用並行節點                

 流程變數和指令碼
   在流程執行過程中可以定義流程變數 分為全域性變數和臨時變數 全域性變數在整個流程中可用 區域性變數在當前節點定義只能在當前節點中使用  一般比如請假 提交請假的天數 請假的時間 可以在請假任務完成後 新增全域性變數   還比如如果有個排他節點 可以
通過請假的天數判斷走哪個審批流程
   所有定義的變數可以是普通的資料型別也可以是物件 在流程定義時可以使用uel表示式來獲取流程變數的值 
 比如 ${userDay} 可以獲取天數 ,判斷 ${userDay<3} 也可以呼叫物件方法 比如 ${user.getUserDay()} 
 表示式可以參考 https://www.activiti.org/userguide/#apiExpressions
 流程變數參考 https://www.activiti.org/userguide/#apiVariables
比如官網圖 定義排他節點(input==1走上面流程 input==2走中間流程 input==3走下面流程) 流程開始時只需要新增一個鍵值對的流程變數 input=某個值 就能決定走哪條線路

二。activiti配置

        ProcessEngines.getDefaultProcessEngine()會在第一次呼叫時 初始化並建立一個流程引擎,以後再呼叫就會返回相同的流程引擎。 使用對應的方法可以建立和關閉所有流程引擎:ProcessEngines.init() 和 ProcessEngines.destroy()。

          ProcessEngines會掃描所有activiti.cfg.xml 和 activiti-context.xml 檔案。 對於activiti.cfg.xml檔案,流程引擎會使用Activiti的經典方式構建:                                         ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine().             對於activiti-context.xml檔案,流程引擎會使用Spring方法構建:先建立一個Spring的環境, 然後通過環境獲得流程引擎。

 所有流程相關的資料都儲存在資料庫中 需要先通過流程引擎配置生成資料庫的表  具體的實現參考官方使用者嚮導
(https://www.activiti.org/userguide/#_configuration)

類路徑下新增 activiti.cfg.xml

<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.xsd">

  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

    <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl" />
    <property name="jdbcDriver" value="oracle.jdbc.driver.OracleDriver" />
    <property name="jdbcUsername" value="ac" />
    <property name="jdbcPassword" value="ac" />

    <property name="databaseSchemaUpdate" value="true" />
  </bean>

</beans>
新增maven依賴
<dependencies>
		<!-- https://mvnrepository.com/artifact/org.activiti/activiti-engine -->
		<dependency>
			<groupId>org.activiti</groupId>
			<artifactId>activiti-engine</artifactId>
			<version>5.22.0</version>
		</dependency>
<!-- https://mvnrepository.com/artifact/com.hynnet/oracle-driver-ojdbc -->
<dependency>
    <groupId>com.hynnet</groupId>
    <artifactId>oracle-driver-ojdbc</artifactId>
    <version>12.1.0.2</version>
</dependency>
</dependencies>

獲取流程例項 自動建立表

package activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;

public class TestCreateDb {

	public static void main(String[] args) {
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	}

}

執行main方法 檢視資料庫 發現產生了25張表


Activiti的表都以ACT_開頭。 第二部分是表示表的用途的兩個字母標識。 用途也和服務的API對應。

  1. ACT_RE_*: 'RE'表示repository。 這個字首的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。
  2. ACT_RU_*: 'RU'表示runtime。 這些執行時的表,包含流程例項,任務,變數,非同步任務,等執行中的資料。 Activiti只在流程例項執行過程中儲存這些資料, 在流程結束時就會刪除這些記錄。 這樣執行時表可以一直很小速度很快。
  3. ACT_ID_*: 'ID'表示identity。 這些表包含身份資訊,比如使用者,組等等。
  4. ACT_HI_*: 'HI'表示history。 這些表包含歷史資料,比如歷史流程例項, 變數,任務等等。
  5. ACT_GE_*: 通用資料, 用於不同場景下。

三。activiti 例項,bpmn及常用api操作

以下通過一個流程例項顯示 activiti的所有相關api操作 

模擬例項 比如威客網站中某個僱主釋出了一個單人懸賞的任務 此時不同的威客都可以發起投稿投標的流程  流程圖如下

威客開啟一個流程定義流程變數(威客使用者id)威客交稿的任務當前威客通過威客id可以查詢到任務  威客交稿任務

 開始 使用者需要傳遞投稿的任務編號 僱主資訊 稿件資訊 完成任務後 僱主選稿 選稿任務完成 需要進入排他路由 選中
和未選中通過一個流程變數來控制  如果未選中 直接傳送落選郵件到威客賬號 選中繼續後 使用並行路由 同時開啟兩個流程
(傳送通知郵件 ,威客提交終稿)是同時執行 互不影響  只演示前半部分 後面部分相似
bpmn的原始碼 

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="inviteProcess" name="inviteProcess" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="wkInvite" name="威客交稿" activiti:assignee="${userWk}"></userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="wkInvite"></sequenceFlow>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <serviceTask id="mailtask1" name="傳送落選郵件" activiti:type="mail">
      <extensionElements>
        <activiti:field name="to">
          <activiti:expression><![CDATA[${email_to}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="from">
          <activiti:expression><![CDATA[${email_from}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="subject">
          <activiti:expression><![CDATA[${email_title}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="html">
          <activiti:expression><![CDATA[${email_content}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="charset">
          <activiti:string><![CDATA[utf-8]]></activiti:string>
        </activiti:field>
      </extensionElements>
    </serviceTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="mailtask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${shortlist==0}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow5" sourceRef="mailtask1" targetRef="endevent1"></sequenceFlow>
    <parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway>
    <serviceTask id="mailtask2" name="傳送中標郵件" activiti:type="mail">
      <extensionElements>
        <activiti:field name="to">
          <activiti:expression><![CDATA[${email_to}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="from">
          <activiti:expression><![CDATA[${email_from}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="subject">
          <activiti:expression><![CDATA[${email_title}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="html">
          <activiti:expression><![CDATA[${email_content}]]></activiti:expression>
        </activiti:field>
        <activiti:field name="charset">
          <activiti:string><![CDATA[utf-8]]></activiti:string>
        </activiti:field>
      </extensionElements>
    </serviceTask>
    <sequenceFlow id="flow6" sourceRef="exclusivegateway1" targetRef="parallelgateway1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${shortlist==1}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="usertask1" name="提交最終稿件" activiti:assignee="${userWk}"></userTask>
    <sequenceFlow id="flow7" sourceRef="parallelgateway1" targetRef="mailtask2"></sequenceFlow>
    <sequenceFlow id="flow8" sourceRef="parallelgateway1" targetRef="usertask1"></sequenceFlow>
    <userTask id="usertask2" name="僱主確認" activiti:assignee="${employer}"></userTask>
    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow9" sourceRef="exclusivegateway2" targetRef="usertask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${ifaccept==0}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow10" sourceRef="usertask2" targetRef="exclusivegateway2"></sequenceFlow>
    <sequenceFlow id="flow11" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
    <userTask id="usertask3" name="威客收款" activiti:assignee="${userWk}"></userTask>
    <sequenceFlow id="flow12" sourceRef="exclusivegateway2" targetRef="usertask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${ifaccept==1}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endevent2" name="End"></endEvent>
    <sequenceFlow id="flow13" sourceRef="usertask3" targetRef="endevent2"></sequenceFlow>
    <endEvent id="endevent3" name="End"></endEvent>
    <sequenceFlow id="flow14" sourceRef="mailtask2" targetRef="endevent3"></sequenceFlow>
    <userTask id="usertask4" name="僱主選稿" activiti:assignee="${employer}"></userTask>
    <sequenceFlow id="flow15" sourceRef="wkInvite" targetRef="usertask4"></sequenceFlow>
    <sequenceFlow id="flow16" sourceRef="usertask4" targetRef="exclusivegateway1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_inviteProcess">
    <bpmndi:BPMNPlane bpmnElement="inviteProcess" id="BPMNPlane_inviteProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="0.0" y="172.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="wkInvite" id="BPMNShape_wkInvite">
        <omgdc:Bounds height="55.0" width="105.0" x="60.0" y="162.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="300.0" y="169.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="mailtask1" id="BPMNShape_mailtask1">
        <omgdc:Bounds height="55.0" width="105.0" x="380.0" y="216.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="415.0" y="380.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="parallelgateway1" id="BPMNShape_parallelgateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="380.0" y="110.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="mailtask2" id="BPMNShape_mailtask2">
        <omgdc:Bounds height="55.0" width="105.0" x="470.0" y="56.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="470.0" y="135.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="640.0" y="135.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
        <omgdc:Bounds height="40.0" width="40.0" x="672.0" y="223.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
        <omgdc:Bounds height="55.0" width="105.0" x="640.0" y="300.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent2" id="BPMNShape_endevent2">
        <omgdc:Bounds height="35.0" width="35.0" x="675.0" y="414.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent3" id="BPMNShape_endevent3">
        <omgdc:Bounds height="35.0" width="35.0" x="670.0" y="66.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4">
        <omgdc:Bounds height="55.0" width="105.0" x="180.0" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="35.0" y="189.0"></omgdi:waypoint>
        <omgdi:waypoint x="60.0" y="189.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="320.0" y="209.0"></omgdi:waypoint>
        <omgdi:waypoint x="320.0" y="243.0"></omgdi:waypoint>
        <omgdi:waypoint x="380.0" y="243.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
        <omgdi:waypoint x="432.0" y="271.0"></omgdi:waypoint>
        <omgdi:waypoint x="432.0" y="380.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
        <omgdi:waypoint x="320.0" y="169.0"></omgdi:waypoint>
        <omgdi:waypoint x="320.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="353.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="388.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="388.0" y="138.0"></omgdi:waypoint>
        <omgdi:waypoint x="420.0" y="130.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
        <omgdi:waypoint x="400.0" y="110.0"></omgdi:waypoint>
        <omgdi:waypoint x="400.0" y="83.0"></omgdi:waypoint>
        <omgdi:waypoint x="470.0" y="83.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
        <omgdi:waypoint x="400.0" y="150.0"></omgdi:waypoint>
        <omgdi:waypoint x="400.0" y="162.0"></omgdi:waypoint>
        <omgdi:waypoint x="470.0" y="162.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
        <omgdi:waypoint x="692.0" y="223.0"></omgdi:waypoint>
        <omgdi:waypoint x="522.0" y="190.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
        <omgdi:waypoint x="692.0" y="190.0"></omgdi:waypoint>
        <omgdi:waypoint x="692.0" y="223.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
        <omgdi:waypoint x="575.0" y="162.0"></omgdi:waypoint>
        <omgdi:waypoint x="640.0" y="162.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
        <omgdi:waypoint x="692.0" y="263.0"></omgdi:waypoint>
        <omgdi:waypoint x="692.0" y="300.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
        <omgdi:waypoint x="692.0" y="355.0"></omgdi:waypoint>
        <omgdi:waypoint x="692.0" y="414.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
        <omgdi:waypoint x="575.0" y="83.0"></omgdi:waypoint>
        <omgdi:waypoint x="670.0" y="83.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
        <omgdi:waypoint x="165.0" y="189.0"></omgdi:waypoint>
        <omgdi:waypoint x="180.0" y="191.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
        <omgdi:waypoint x="285.0" y="191.0"></omgdi:waypoint>
        <omgdi:waypoint x="300.0" y="189.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
演示程式碼如下
 假定流程引擎物件已經如下定義
//建立流程引擎物件
	private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

步驟1 釋出流程定義

/**
	 * 釋出流程 添加發布bpmn和圖片 也可以打包成  zip釋出
	 * 
	 */
	@Test
	public void deployProcess() {
		//用於釋出流程資源 以及流程定義
		RepositoryService repositoryService = processEngine.getRepositoryService();
		Deployment deploy = repositoryService.createDeployment()
			.addClasspathResource("diagrams/MyProcess.bpmn")
			.addClasspathResource("diagrams/MyProcess.png")
			//.addZipInputStream(zipInputStream) 可以新增壓縮包 web定義流程就可以使用這個方法上傳
			.name("威客單人投標流程")
			.deploy();
		//資原始檔在act_ge_bytearray表中
		//流程定義在act_re_procdef表中
		System.out.println("流程定義id:"+deploy.getId());
		System.out.println("流程定義名稱:"+deploy.getName());
		System.out.println("流程定義釋出時間:"+deploy.getDeploymentTime().toGMTString());
		//檢視釋出的流程資訊 檢視釋出的流程總和
		long count = repositoryService.createDeploymentQuery().count();
		System.out.println("總流程定義數:"+count);
	}
步驟2 zs檢視自己的任務編號 完成投稿任務
檢視任務
/**
	 * 執行流程
	 * 相同的流程被髮布(id不同 _key相同)多, 每釋出 一次 ACT_RE_PROCDEF 多一條資料, Version都會加1,
	 *    根據key來啟動 會啟動最新版本號的流程定義
	 *   如果想執行舊的流程定義就可以使用id來啟動
	 * 模擬場景 某個威客 開始向某個任務投稿 任務就開始了  
	 */
	@Test
	public void startProcess() {
		//執行流程使用runtimesErvice
		RuntimeService runtimeService = processEngine.getRuntimeService();
		//流程變數 傳入是誰啟動的流程
		Map map=new HashMap();
		map.put("userWk", "zs");
		//key就是流程圖的 id (注意不是資料庫裡面的id 資料庫裡面的key是流程裡開始定義的id)
		//流程例項資料在 ACT_RU_EXECUTION表中 
		//流程變數 在 ACT_RU_VARIABLE中
		//使用者任務在 ACT_RU_TASK中
		ProcessInstance  instance= runtimeService.startProcessInstanceByKey("inviteProcess",map);
		System.out.println("使用者"+map.get("userWk")+"開啟了一個投稿流程");
		System.out.println("流程例項編號是:"+instance.getProcessInstanceId());
		long count = runtimeService.createExecutionQuery().count();
		System.out.println("總流程例項數:"+count);
	}

完成任務

/**
	 * 張三完成任務 就需要交稿 定義流程變數
	 */
	@Test
	public void submitTask() {
		//使用者任務的完成 使用TaskService
		TaskService taskService = processEngine.getTaskService();
		String taskId="20005";
		Map map=new HashMap();
		/**
		 * 張三交稿資料
		 * **/
		map.put("employer", "ls");//設定任務的僱主
		map.put("taskNo", "僱主任務編號");
		map.put("taskContent", "用字串模擬");
		
		
		taskService.complete(taskId, map);
	}	

步驟3 僱主ls檢視自己的任務編號 完成選稿稿任務這裡模擬shortlist==0表示沒選中 進入傳送郵件結束流程的步驟 

需要配置郵件的smtp和使用者密碼資訊 修改activiti.cfg.xml 新增


<property name="mailServerHost" value="smtp.126.com" />
    <property name="mailServerPort" value="25" />
    <property name="mailServerUsername" value="[email protected]"></property>
    <property name="mailServerPassword" value="XXXXXXXXXX您的郵箱密碼"></property>
未選中程式碼
/**
	 * 李四完成任務 就需要選稿  
	 */
	@Test
	public void submitTask() {
		//使用者任務的完成 使用TaskService
		TaskService taskService = processEngine.getTaskService();
		String taskId="20005";
		Map map=new HashMap();
		
		map.put("shortlist", 0);
		map.put("email_to", "[email protected]");
		map.put("email_from", "[email protected]");
		map.put("email_title", "[email protected]");
		map.put("email_content", "您對僱主任務編號"+taskService.getVariable(taskId, "taskNo")+"的投稿稿件 已經落選。。");
		
		taskService.complete(taskId, map);
	}	
選中程式碼
/**
	 * 李四完成任務 就需要選稿  
	 */
	@Test
	public void submitTask() {
		//使用者任務的完成 使用TaskService
		TaskService taskService = processEngine.getTaskService();
		String taskId="20005";
		Map map=new HashMap();
		
		map.put("shortlist", 1);
		map.put("email_to", "[email protected]");
		map.put("email_from", "[email protected]");
		map.put("email_title", "[email protected]");
		map.put("email_content", "您對僱主任務編號"+taskService.getVariable(taskId, "taskNo")+"的投稿稿件 已經被選中 請完成終稿。。");
		
		taskService.complete(taskId, map);
	}	

其他程式碼就不演示 具體參考https://www.activiti.org/userguide/#chapterApi

四。springboot整合activiti

 整合web參考  https://www.activiti.org/userguide/#springintegration

相關推薦

工作引擎Activiti使用自我總結

轉載自:工作流引擎Activiti使用總結 1.簡單介工作流引擎與Activiti 對於工作流引擎的解釋請參考百度百科:工作流引擎 1.1 我與工作流引擎 在第一家公司工作的時候主要任務就是開發OA系統,當然基本都是有工作流的支援,不過當時使用的工作流引擎是公司一些牛人開發的(據

工作引擎activiti

一。activiti簡介      Activiti專案是一項新的基於Apache許可的開源BPM平臺,從基礎開始構建,旨在提供支援新的BPMN 2.0標準,包括支援物件管理組(OMG),面對新技術的機遇,諸如互操作性和雲架構,提供技術實現。       創始人Tom Bae

工作引擎Activiti系列(一)——初識

1、介紹     幾乎任何一個公司的軟體開發都會涉及到流程,以往我們可能是這麼實現的:業務表新增標誌位標識流程的節點狀態,關聯批註表實現稽核意見,根據一些業務資料分析處理邏輯,分配任務到使用者,節點的排程,審批等.....這其實是很繁瑣的,且不說開發起來比較混亂,維護起來更

工作引擎Activiti使用總結

1.簡單介工作流引擎與Activiti 對於工作流引擎的解釋請參考百度百科:工作流引擎 1.1 我與工作流引擎 在第一家公司工作的時候主要任務就是開發OA系統,當然基本都是有工作流的支援,不過當時使用的工作流引擎是公司一些牛人開發的(據說是用一個開源的引擎修改的),名稱叫CoreFlow;功

工作引擎Activiti與SpringBoot2整合--開源軟體誕生17

開源ERP技術整合系列--第17篇 用日誌記錄“開源軟體”的誕生 【點亮星標】----祈盼著一個鼓勵 博主開源地址: 碼雲:https://gitee.com/redragon/redragon-erp GitHub:https://github.com/redragon1985/redragon-erp

Activiti工作引擎數據庫表結構

activit let repr 通過 運行時 工作流 用例 pro ext Activiti工作流引擎數據庫表結構 一、數據庫表的命名   Acitiviti數據庫中表的命名都是以ACT_開頭的。第二部分是一個兩個字符用例表的標識。此用例大體與服務API是匹配的。 l

Java Activiti 工作引擎 springmvc SSM 流程審批 後臺框架源碼

Activiti6.0工作流模塊----------------------------------------------------------------------------------------------------------1.模型管理 :web在線流程設計器、預覽流程xml、導出x

Java Activiti 工作引擎 流程審批 後臺框架源碼 springmvc SSM

物流查詢接口 主表 快速 font sql www. 物流 sock hit 博文來源:http://www.fhadmin.org/webnewsdetail1.html工作流模塊----------------------------------------------

Activiti工作引擎學習總結

經過這三天對與Activiti的軟磨硬泡,也算是小有所獲。 想要學會工作流引擎其實很簡單,搞清楚processengine (Activiti引擎),並且理解其中幾大服務介面: 服務:    reposit

Activiti工作引擎學習及流程設計器的安裝(Eclipse外掛)

工作流簡介     我們先來描述一個在工作中經常用到的一個流程:請假     員工張三請假一天 主管王五批准     員工李四請假一天 主管王五不批准  &nbs

ActivitiActiviti工作引擎 - 提交審批和審批處理示例詳解 【精品】

       在上一篇的文章中,我給大家分享了Activiti工作流引擎的API的封裝程式碼,通過我們自己封裝的程式碼,在實際的專案中我們就可以進行工作流相關的開發了。以下內容我們分三個部分:提交審批,審批列表查詢,審批處理。 一、提交審批 &nb

工作引擎JFlow與activiti 對比分析(一)5種基本控制模式的對比

為了更好的說明activiti 與jflow的兩款工作流引擎的特點與區別,我們按照如下幾個方面做一次全面的、客觀的對比。       首先activiti是國外的一款開源的工作流程引擎,在國際上影響比較深遠與廣泛,解決了BPM領域的很多問題,值得我們讚賞。他

馳騁工作引擎JFlow與activiti的對比之4種高階分支同步模式

多重選擇(Multiple Choice) 在流程中,當一個活動完成後,有多個分支進行選擇,可以選擇執行其中的一個或者N個分支。 例子:比如去世博園玩,在門口檢票後,可以選擇A-E個片區中的N個進行觀光。     ACTIVITI 中的支援情況: 1.JPDL方式不支

馳騁工作引擎JFlow與activiti的對比之2種結構化模式

1. 任意迴圈(Arbitrary Cycles) ACTIVITI : 某一個或多個活動可以反覆執行。 例子:使用者買了瓶汽水,拿到汽水後,中了一瓶,又去兌換了一瓶汽水,如果又中了,再去兌換一瓶汽水…. JFLOW: 完全是條件判斷,在表單中增加一個稽核元件,就可以把每次校驗的資訊,寫入裡面,

Activiti教程(二)activiti工作引擎結構講解

快速掌握activiti: 1.下載activiti看下結構  2.部署下activiti-admin 控制檯 3.瞭解流程定義-部署-執行 4.學著使用控制檯 5.開始編碼 一.工作流引擎結構 二.初始化表結構  28張表 比以前的版本多幾張

馳騁工作引擎JFlow與activiti的對比之3種基於狀態的模式

延遲選擇(Deferred Choice) 流程中某個點可以有多個分支進行選擇。不是基於簡單的資料或者決定就可以很明顯地作出選擇,而是會向系統或者執行環境提供多種可選擇的分支;但是又不同於AND-Split模式,延遲選擇只能選擇一個分支執行,一旦選擇了其中第一個分支,那麼其他分支就會被

馳騁工作引擎JFlow與activiti的對比之4種包含多例項的模式

無同步的多例項(MIwithout) 在流程中,一個活動可以啟用多個例項,每個例項相互獨立,並不需要在後面進行同步。 例子:比如使用者購買了N本書,於是後續的支付賬單、更新客戶可以以本書為單位各自執行。 ACTIVITI 中的支援情況: 支援這種模式,但是不允許在後面進行結束動

馳騁工作引擎JFlow與activiti的對比之5種基本控制模式的對比

前言 為了更好的說明activiti 與jflow的兩款工作流引擎的特點與區別,我們按照如下幾個方面做一次全面的、客觀的對比。       首先activiti是國外的一款開源的工作流程引擎,在國際上影響比較深遠與廣泛,解決了BPM領域的很多

馳騁工作引擎JFlow與activiti的對比 -總結

共同點: 1. 嵌入式的工作流引擎,降低叢集複雜性。 2. 嚴格而靈活的流程版本控制 3. 支援多種資料庫 4. 支援多種流程設計模式 5. 成熟度高的開源工作流,具有可靠的穩定性和效能。 區別: 1. 流程定義方式: ACTIVITI :採用xml的方式,通過拼字串的方式完成,所以流程定

Activiti工作引擎web設計不顯示問題總結

首先開啟官網地址:http://mvnrepository.com/artifact/org.activiti/activiti-webapp-explorer2下載最新的war包,然後解壓後,放到tomcat的webapp下。1、首先要將應用名稱改為activiti-exp