Activiti工作流實戰筆記之(一)初始環境的搭建

一、基本介紹

       本人是個資料控,學習某項技術總要把這項技術的所有資料都蒐羅起來,綜合的去學習,慢慢的去啃。學習Activiti已經有2個月了,現就一些基本心得作一些記錄,有寫錯的地方還望大神指正,畢竟還是個小白。

      目前關於activiti的書籍,市面上有三本,主要是瘋狂軟件楊恩雄編著的《瘋狂Activiti工作流》,閆洪磊的《Activiti實戰》,冀正的《Activiti權威指南》,個人感覺,三者都有所長,學習順序可以按照我列出的先後順序去學習,還是強烈推薦第二本,非常的實用。

      視頻課程的話我只看過某站老雷和某馬的以及CSDN學院賴國榮老師講的課程。初學者還是比較推薦賴國榮老師的,看完之後可以看下老雷講的,都是帶有實戰項目的視頻。

二、繪製流程圖

     做工作流,畫流程圖肯定是必不可少的。個人偏向於用eclipse安裝繪製流程圖插件去畫,插件的安裝方式前輩們都已寫過好多博客了,大家參考安裝即可。下面以一個生活中的例子,請假的審批來說說流程圖的繪製。

     一個請假的審批流程,需要職員首先填寫請假單,然後交由所在部門的組長去審批,組長可以選擇同意或者是不同意,圖中一個X號是一個排他網關,代表流程會選擇其中一條路徑進行下去。如果選擇了同意請假,那麼下一步交由科長審批,科長審批完,該流程也就結束了。如果組長不同意請假,流程會走到“職員修改或放棄”,職員同樣可以自己是修改我的請假請求還是直接放棄申請。如果放棄申請,那麼流程便走向結束,如果修改申請,流程會返回填寫請假單的任務。這就是這個流程的大概走向。

      下面說一下各個節點的需要注意的地方:

      (一)啓動節點的配置

        上述流程圖中啓動事件爲一個空啓動事件,一般情況下會在MainConfig中的Initiator屬性中設定一個變量,然後在項目中配合identityService.setAuthenticatedUserId方法,用來記錄流程的發起人。具體爲:

       

      

identityService.setAuthenticatedUserId("用戶ID")

     (二)用戶任務的配置

       流程圖中的黃色圓角矩形均爲用戶任務,有的地方也成爲“活動”,用戶任務主要配置的內容有如下內容

       首先是職員填寫請假單任務:

       1、general

       

        id需要用戶自己爲該項“任務”(我覺得用活動更貼切一點,以防和數據庫表中的任務id混淆)定義一個id,name當然是起個名字了。

      2、MainConfig

       

       先說Assigne,意爲爲這個任務指定一個辦理人,填寫的是用戶的ID。在做這個實例之前,我準備瞭如下幾個用戶,用戶的信息保存在activiti流程引擎自動創建的25張表的act_id_user表中,用戶的設定可以在大家搭建完環境之後再設定。此處爲大家好理解故而提前說明。貼出我準備的用戶信息:

       

       說回Assignee的設定,途中的任務辦理人用了${applyUserId}的方式引用了變量applyUserId的值,applyUserId的值前面已經說過是啓動流程的人人的ID,所以爲第一個任務的辦理人指定爲流程的發起人。聯想一下現實生活中的情景,我要發起一個請假流程,填寫請假單當然也是我自己了。

       之後通過組長審批任務的設定我們對比看下Assignee

       因爲組長通常是固定的一個人,所有此處我們之間把Assignee設定爲組長的ID,同理,科長也是之間設定科長的id。至於下面的候選用戶與候選用戶組,暫時不說。

       

      (三)排他網關流程走向的控制

       我們先之間看圖:

       

      流程走向是通過設定條件來滿足,例如途中,直接在流程指向上設定某個條件,例如途中${groupLeaderApproved=='true'},當組長完成他的任務的時候,可以傳一個流程變量groupLeaderApproved進去,令groupLeaderApproved爲true,表明組長同意了請假,流程自動走到科長審批環節,同理,否定的設定${groupLeaderApproved=='false'}。基本需要注意的也就這些,像監聽器,表單日後再說。下面貼出流程圖的完成Xml文件:

    

<?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: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="official_document" name="某局請假審批" isExecutable="true">
    <startEvent id="startevent1" name="Start" activiti:initiator="applyUserId"></startEvent>
    <userTask id="workerApply" name="職員填寫請假單" activiti:assignee="${applyUserId}"></userTask>
    <userTask id="groupLeaderCheck" name="組長審批" activiti:assignee="groupLeader"></userTask>
    <userTask id="sectionChiefCheck" name="科長審批" activiti:assignee="sectionChief"></userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="workerApply"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="workerApply" targetRef="groupLeaderCheck"></sequenceFlow>
    <sequenceFlow id="flow4" sourceRef="sectionChiefCheck" targetRef="endevent1"></sequenceFlow>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow5" sourceRef="groupLeaderCheck" targetRef="exclusivegateway1"></sequenceFlow>
    <sequenceFlow id="flow6" sourceRef="exclusivegateway1" targetRef="sectionChiefCheck">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${groupLeaderApproved=='true'}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="usertask1" name="職員修改或放棄" activiti:assignee="${applyUserId}"></userTask>
    <sequenceFlow id="flow7" sourceRef="exclusivegateway1" targetRef="usertask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${groupLeaderApproved=='false'}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow9" sourceRef="usertask1" targetRef="exclusivegateway2"></sequenceFlow>
    <sequenceFlow id="flow10" sourceRef="exclusivegateway2" targetRef="endevent1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${workerChangeApply=='false'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow11" sourceRef="exclusivegateway2" targetRef="workerApply">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${workerChangeApply=='true'}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_official_document">
    <bpmndi:BPMNPlane bpmnElement="official_document" id="BPMNPlane_official_document">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="220.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="workerApply" id="BPMNShape_workerApply">
        <omgdc:Bounds height="55.0" width="131.0" x="220.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="groupLeaderCheck" id="BPMNShape_groupLeaderCheck">
        <omgdc:Bounds height="55.0" width="105.0" x="450.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sectionChiefCheck" id="BPMNShape_sectionChiefCheck">
        <omgdc:Bounds height="55.0" width="105.0" x="710.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="930.0" y="220.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="600.0" y="217.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="137.0" x="552.0" y="330.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
        <omgdc:Bounds height="40.0" width="40.0" x="600.0" y="440.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="125.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="220.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="351.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="450.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="815.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="930.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
        <omgdi:waypoint x="555.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="600.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
        <omgdi:waypoint x="640.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="710.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
        <omgdi:waypoint x="620.0" y="257.0"></omgdi:waypoint>
        <omgdi:waypoint x="620.0" y="330.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
        <omgdi:waypoint x="620.0" y="385.0"></omgdi:waypoint>
        <omgdi:waypoint x="620.0" y="440.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
        <omgdi:waypoint x="640.0" y="460.0"></omgdi:waypoint>
        <omgdi:waypoint x="947.0" y="459.0"></omgdi:waypoint>
        <omgdi:waypoint x="947.0" y="255.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
        <omgdi:waypoint x="600.0" y="460.0"></omgdi:waypoint>
        <omgdi:waypoint x="285.0" y="459.0"></omgdi:waypoint>
        <omgdi:waypoint x="285.0" y="265.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

三、基於SSM框架整合工作流的初始環境搭建

     ssm搭建的過程我就不說了,大家應該都會,主要說一下整合Activiti,如果需要源碼我可以發出來供大家參考。

    一、POM文件

    

<!-- 配置版本 -->
    <properties>
        <spring.version>4.3.17.RELEASE</spring.version>
        <mysql.version>5.1.39</mysql.version>
        <!-- 注意只能使用2.0以下的版本 -->
        <activiti.version>5.22.0</activiti.version>
        <mybatis.version>3.4.6</mybatis.version>
        <!-- 注意只能使用2.0以下的版本 -->
        <log4j.version>1.2.17</log4j.version>
    </properties>
 
    <dependencies>
        <!-- activiti的依賴 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- ssm集成的時候使用 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- mysql驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
 
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <!-- 配置編譯的jdk版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <!-- 指定source和target的版本 -->
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

        二、Acitiviti的配置文件

        

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!--配置activiti的主鍵生成器-->
    <bean id="uuidGenerator" class="org.activiti.engine.impl.persistence.StrongUuidGenerator" />
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
        <!-- 數據源 -->
        <property name="dataSource" ref="pooledDataSource" />
        <!-- 配置事務管理器,統一事務 -->
        <property name="transactionManager" ref="transactionManager" />
        <!-- 設置建表策略 -->
        <property name="databaseSchemaUpdate" value="true" />
    </bean>

    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>
    <!-- 
        bean id repositoryService
        RepositoryServicie repositoryService = processEngine.getRepositoryService();
     -->
    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
    <bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
    <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
    <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
</beans>

  當然還有數據庫文件,log4j我就不貼了。下一篇我們說說各種服務

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章