<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          史上最全的工作流引擎 Activiti 學(xué)習(xí)教程(值得收藏)

          共 60316字,需瀏覽 121分鐘

           ·

          2022-07-06 11:15

          關(guān)注我們,設(shè)為星標,每天7:40不見不散,架構(gòu)路上與您共享

          回復(fù)架構(gòu)師獲取資源


          大家好,我是你們的朋友架構(gòu)君,一個會寫代碼吟詩的架構(gòu)師。

          'javajgs.com';

          一、工作流介紹

          1.1 概念

          工作流(Workflow),就是通過計算機對業(yè)務(wù)流程自動化執(zhí)行管理。它主要解決的是“使在多個參與者之間按照某種預(yù)定義的規(guī)則自動進行傳遞文檔、信息或任務(wù)的過程,從而實現(xiàn)某個預(yù)期的業(yè)務(wù)目標,或者促使此目標的實現(xiàn)”。

          1.2 工作流系統(tǒng)

          一個軟件系統(tǒng)中具有工作流的功能,我們把它稱為工作流系統(tǒng),一個系統(tǒng)中工作流的功能是什么?就是對系統(tǒng)的業(yè)務(wù)流程進行自動化管理,所以工作流是建立在業(yè)務(wù)流程的基礎(chǔ)上,所以一個軟件的系統(tǒng)核心根本上還是系統(tǒng)的業(yè)務(wù)流程,工作流只是協(xié)助進行業(yè)務(wù)流程管理。即使沒有工作流業(yè)務(wù)系統(tǒng)也可以開發(fā)運行,只不過有了工作流可以更好的管理業(yè)務(wù)流程,提高系統(tǒng)的可擴展性。

          1.3 適用行業(yè)

          消費品行業(yè),制造業(yè),電信服務(wù)業(yè),銀證險等金融服務(wù)業(yè),物流服務(wù)業(yè),物業(yè)服務(wù)業(yè),物業(yè)管理,大中型進出口貿(mào)易公司,政府事業(yè)機構(gòu),研究院所及教育服務(wù)業(yè)等,特別是大的跨國企業(yè)和集團公司。

          1.4 具體應(yīng)用

          1、關(guān)鍵業(yè)務(wù)流程: 訂單、報價處理、合同審核、客戶電話處理、供應(yīng)鏈管理等

          2、行政管理類: 出差申請、加班申請、請假申請、用車申請、各種辦公用品申請、購買申請、日報周報等凡是原來手工流轉(zhuǎn)處理的行政表單。

          3、人事管理類: 員工培訓(xùn)安排、績效考評、職位變動處理、員工檔案信息管理等。

          4、財務(wù)相關(guān)類: 付款請求、應(yīng)收款處理、日常報銷處理、出差報銷、預(yù)算和計劃申請等。

          5、客戶服務(wù)類: 客戶信息管理、客戶投訴、請求處理、售后服務(wù)管理等。

          6、特殊服務(wù)類: ISO系列對應(yīng)流程、質(zhì)量管理對應(yīng)流程、產(chǎn)品數(shù)據(jù)信息管理、貿(mào)易公司報關(guān)處理、物流公司貨物跟蹤處理等各種通過表單逐步手工流轉(zhuǎn)完成的任務(wù)均可應(yīng)用工作流軟件自動規(guī)范地實施。

          1.5 實現(xiàn)方式

          在沒有專門的工作流引擎之前,我們之前為了實現(xiàn)流程控制,通常的做法就是采用狀態(tài)字段的值來跟蹤流程的變化情況。這樣不同角色的用戶,通過狀態(tài)字段的取值來決定記錄是否顯示。

          針對有權(quán)限可以查看的記錄,當(dāng)前用戶根據(jù)自己的角色來決定審批是否合格的操作。如果合格將狀態(tài)字段設(shè)置一個值,來代表合格;當(dāng)然如果不合格也需要設(shè)置一個值來代表不合格的情況。

          這是一種最為原始的方式。通過狀態(tài)字段雖然做到了流程控制,但是當(dāng)我們的流程發(fā)生變更的時候,這種方式所編寫的代碼也要進行調(diào)整。

          那么有沒有專業(yè)的方式來實現(xiàn)工作流的管理呢?并且可以做到業(yè)務(wù)流程變化之后,我們的程序可以不用改變,如果可以實現(xiàn)這樣的效果,那么我們的業(yè)務(wù)系統(tǒng)的適應(yīng)能力就得到了極大提升。

          二、Activiti7概述

          2.1 介紹

          Alfresco軟件在2010年5月17日宣布Activiti業(yè)務(wù)流程管理(BPM)開源項目的正式啟動,其首席架構(gòu)師由業(yè)務(wù)流程管理BPM的專家 Tom Baeyens擔(dān)任,Tom Baeyens就是原來jbpm的架構(gòu)師,而jbpm是一個非常有名的工作流引擎,當(dāng)然activiti也是一個工作流引擎。

          Activiti是一個工作流引擎, activiti可以將業(yè)務(wù)系統(tǒng)中復(fù)雜的業(yè)務(wù)流程抽取出來,使用專門的建模語言BPMN2.0進行定義,業(yè)務(wù)流程按照預(yù)先定義的流程進行執(zhí)行,實現(xiàn)了系統(tǒng)的流程由activiti進行管理,減少業(yè)務(wù)系統(tǒng)由于流程變更進行系統(tǒng)升級改造的工作量,從而提高系統(tǒng)的健壯性,同時也減少了系統(tǒng)開發(fā)維護成本。

          官方網(wǎng)站:https://www.activiti.org/

          經(jīng)歷的版本:

          目前最新版本:Activiti7.0.0.Beta

          2.1.1 BPM

          BPM(Business Process Management),即業(yè)務(wù)流程管理,是一種規(guī)范化的構(gòu)造端到端的業(yè)務(wù)流程,以持續(xù)的提高組織業(yè)務(wù)效率。常見商業(yè)管理教育如EMBA、MBA等均將BPM包含在內(nèi)。

          2.1.2 BPM軟件

          BPM軟件就是根據(jù)企業(yè)中業(yè)務(wù)環(huán)境的變化,推進人與人之間、人與系統(tǒng)之間以及系統(tǒng)與系統(tǒng)之間的整合及調(diào)整的經(jīng)營方法與解決方案的IT工具。

          通過BPM軟件對企業(yè)內(nèi)部及外部的業(yè)務(wù)流程的整個生命周期進行建模、自動化、管理監(jiān)控和優(yōu)化,使企業(yè)成本降低,利潤得以大幅提升。

          BPM軟件在企業(yè)中應(yīng)用領(lǐng)域廣泛,凡是有業(yè)務(wù)流程的地方都可以BPM軟件進行管理,比如企業(yè)人事辦公管理、采購流程管理、公文審批流程管理、財務(wù)管理等。

          2.1.3 BPMN

          BPMN(Business Process Model AndNotation)- 業(yè)務(wù)流程模型和符號 是由BPMI(BusinessProcess Management Initiative)開發(fā)的一套標準的業(yè)務(wù)流程建模符號,使用BPMN提供的符號可以創(chuàng)建業(yè)務(wù)流程。

          2004年5月發(fā)布了BPMN1.0規(guī)范.BPMI于2005年9月并入OMG(The Object Management Group對象管理組織)組織。OMG于2011年1月發(fā)布BPMN2.0的最終版本。

          具體發(fā)展歷史如下:

          BPMN 是目前被各 BPM 廠商廣泛接受的 BPM 標準。Activiti 就是使用 BPMN 2.0 進行流程建模、流程執(zhí)行管理,它包括很多的建模符號,比如:Event

          用一個圓圈表示,它是流程中運行過程中發(fā)生的事情。

          活動用圓角矩形表示,一個流程由一個活動或多個活動組成

          Bpmn圖形其實是通過xml表示業(yè)務(wù)流程,上邊的.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="myProcess" name="My process" isExecutable="true">
              <startEvent id="startevent1" name="Start"></startEvent>
              <userTask id="usertask1" name="創(chuàng)建請假單"></userTask>
              <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
              <userTask id="usertask2" name="部門經(jīng)理審核"></userTask>
              <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
              <userTask id="usertask3" name="人事復(fù)核"></userTask>
              <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
              <endEvent id="endevent1" name="End"></endEvent>
              <sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
            </process>
            <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
              <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
                <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
                  <omgdc:Bounds height="35.0" width="35.0" x="130.0" y="160.0"></omgdc:Bounds>
                </bpmndi:BPMNShape>
                <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
                  <omgdc:Bounds height="55.0" width="105.0" x="210.0" y="150.0"></omgdc:Bounds>
                </bpmndi:BPMNShape>
                <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
                  <omgdc:Bounds height="55.0" width="105.0" x="360.0" y="150.0"></omgdc:Bounds>
                </bpmndi:BPMNShape>
                <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
                  <omgdc:Bounds height="55.0" width="105.0" x="510.0" y="150.0"></omgdc:Bounds>
                </bpmndi:BPMNShape>
                <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
                  <omgdc:Bounds height="35.0" width="35.0" x="660.0" y="160.0"></omgdc:Bounds>
                </bpmndi:BPMNShape>
                <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
                  <omgdi:waypoint x="165.0" y="177.0"></omgdi:waypoint>
                  <omgdi:waypoint x="210.0" y="177.0"></omgdi:waypoint>
                </bpmndi:BPMNEdge>
                <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
                  <omgdi:waypoint x="315.0" y="177.0"></omgdi:waypoint>
                  <omgdi:waypoint x="360.0" y="177.0"></omgdi:waypoint>
                </bpmndi:BPMNEdge>
                <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
                  <omgdi:waypoint x="465.0" y="177.0"></omgdi:waypoint>
                  <omgdi:waypoint x="510.0" y="177.0"></omgdi:waypoint>
                </bpmndi:BPMNEdge>
                <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
                  <omgdi:waypoint x="615.0" y="177.0"></omgdi:waypoint>
                  <omgdi:waypoint x="660.0" y="177.0"></omgdi:waypoint>
                </bpmndi:BPMNEdge>
              </bpmndi:BPMNPlane>
            </bpmndi:BPMNDiagram>
          </definitions>

          2.2 使用步驟

          部署activiti

          Activiti是一個工作流引擎(其實就是一堆jar包API),業(yè)務(wù)系統(tǒng)訪問(操作)activiti的接口,就可以方便的操作流程相關(guān)數(shù)據(jù),這樣就可以把工作流環(huán)境與業(yè)務(wù)系統(tǒng)的環(huán)境集成在一起。

          流程定義

          使用activiti流程建模工具(activity-designer)定義業(yè)務(wù)流程(.bpmn文件) 。

          .bpmn文件就是業(yè)務(wù)流程定義文件,通過xml定義業(yè)務(wù)流程。

          流程定義部署

          activiti部署業(yè)務(wù)流程定義(.bpmn文件)。

          使用activiti提供的api把流程定義內(nèi)容存儲起來,在Activiti執(zhí)行過程中可以查詢定義的內(nèi)容

          Activiti執(zhí)行把流程定義內(nèi)容存儲在數(shù)據(jù)庫中

          啟動一個流程實例

          流程實例也叫:ProcessInstance

          啟動一個流程實例表示開始一次業(yè)務(wù)流程的運行。

          在員工請假流程定義部署完成后,如果張三要請假就可以啟動一個流程實例,如果李四要請假也啟動一個流程實例,兩個流程的執(zhí)行互相不影響。

          用戶查詢待辦任務(wù)(Task)

          因為現(xiàn)在系統(tǒng)的業(yè)務(wù)流程已經(jīng)交給activiti管理,通過activiti就可以查詢當(dāng)前流程執(zhí)行到哪了,當(dāng)前用戶需要辦理什么任務(wù)了,這些activiti幫我們管理了,而不需要開發(fā)人員自己編寫在sql語句查詢。

          用戶辦理任務(wù)

          用戶查詢待辦任務(wù)后,就可以辦理某個任務(wù),如果這個任務(wù)辦理完成還需要其它用戶辦理,比如采購單創(chuàng)建后由部門經(jīng)理審核,這個過程也是由activiti幫我們完成了。

          流程結(jié)束

          當(dāng)任務(wù)辦理完成沒有下一個任務(wù)結(jié)點了,這個流程實例就完成了。

          三、Activiti環(huán)境

          3.1 開發(fā)環(huán)境

          • Jdk1.8或以上版本

          • Mysql 5及以上的版本

          • Tomcat8.5

          • IDEA

          注意:activiti的流程定義工具插件可以安裝在IDEA下,也可以安裝在Eclipse工具下

          3.2 Activiti環(huán)境

          我們使用:Activiti7.0.0.Beta1 默認支持spring5

          3.2.1 下載activiti7

          Activiti下載地址:http://activiti.org/download.html ,Maven的依賴如下:

          <dependencyManagement>
             <dependencies>
                 <dependency>
                     <groupId>org.activiti</groupId>
                     <artifactId>activiti-dependencies</artifactId>
                     <version>7.0.0.Beta1</version>
                     <scope>import</scope>
                     <type>pom</type>
                 </dependency>
             </dependencies>
          </dependencyManagement>
          1) Database:

          activiti運行需要有數(shù)據(jù)庫的支持,支持的數(shù)據(jù)庫有:h2, mysql, oracle, postgres, mssql, db2。

          3.2.2 流程設(shè)計器IDEA下安裝

          在IDEA的File菜單中找到子菜單”Settings”,后面我們再選擇左側(cè)的“plugins”菜單,如下圖所示:

          此時我們就可以搜索到actiBPM插件,它就是Activiti Designer的IDEA版本,我們點擊Install安裝。

          安裝好后,頁面如下:

          提示需要重啟idea,點擊重啟。

          重啟完成后,再次打開Settings 下的 Plugins(插件列表),點擊右側(cè)的Installed(已安裝的插件),在列表中看到actiBPM,就說明已經(jīng)安裝成功了,如下圖所示:

          后面的課程里,我們會使用這個流程設(shè)計器進行Activiti的流程設(shè)計。

          3.3 Activiti的數(shù)據(jù)庫支持

          Activiti 在運行時需要數(shù)據(jù)庫的支持,使用25張表,把流程定義節(jié)點內(nèi)容讀取到數(shù)據(jù)庫表中,以供后續(xù)使用。

          3.3.1 Activiti 支持的數(shù)據(jù)庫

          activiti 支持的數(shù)據(jù)庫和版本如下:

          3.3.2 在MySQL生成表

          3.3.2.1 創(chuàng)建數(shù)據(jù)庫

          創(chuàng)建 mysql 數(shù)據(jù)庫 activiti (名字任意):

          CREATE DATABASE activiti DEFAULT CHARACTER SET utf8;

          3.3.2.2 使用java代碼生成表

          • 創(chuàng)建 java 工程

          使用idea 創(chuàng)建 java 的maven工程,取名:activiti01。

          • 加入 maven 依賴的坐標(jar 包)

          首先需要在 java 工程中加入 ProcessEngine 所需要的 jar 包,包括:

          1. activiti-engine-7.0.0.beta1.jar
          2. activiti 依賴的 jar 包:mybatis、 alf4j、 log4j 等
          3. activiti 依賴的 spring 包
          4. mysql數(shù)據(jù)庫驅(qū)動
          5. 第三方數(shù)據(jù)連接池 dbcp
          6. 單元測試 Junit-4.12.jar

          我們使用 maven 來實現(xiàn)項目的構(gòu)建,所以應(yīng)當(dāng)導(dǎo)入這些 jar 所對應(yīng)的坐標到 pom.xml 文件中。

          完整的依賴內(nèi)容如下:

          <properties>
              <slf4j.version>1.6.6</slf4j.version>
              <log4j.version>1.2.12</log4j.version>
              <activiti.version>7.0.0.Beta1</activiti.version>
          </properties>
          <dependencies>
              <dependency>
                  <groupId>org.activiti</groupId>
                  <artifactId>activiti-engine</artifactId>
                  <version>${activiti.version}</version>
              </dependency>
              <dependency>
                  <groupId>org.activiti</groupId>
                  <artifactId>activiti-spring</artifactId>
                  <version>${activiti.version}</version>
              </dependency>
              <!-- bpmn 模型處理 -->
              <dependency>
                  <groupId>org.activiti</groupId>
                  <artifactId>activiti-bpmn-model</artifactId>
                  <version>${activiti.version}</version>
              </dependency>
              <!-- bpmn 轉(zhuǎn)換 -->
              <dependency>
                  <groupId>org.activiti</groupId>
                  <artifactId>activiti-bpmn-converter</artifactId>
                  <version>${activiti.version}</version>
              </dependency>
              <!-- bpmn json數(shù)據(jù)轉(zhuǎn)換 -->
              <dependency>
                  <groupId>org.activiti</groupId>
                  <artifactId>activiti-json-converter</artifactId>
                  <version>${activiti.version}</version>
              </dependency>
              <!-- bpmn 布局 -->
              <dependency>
                  <groupId>org.activiti</groupId>
                  <artifactId>activiti-bpmn-layout</artifactId>
                  <version>${activiti.version}</version>
              </dependency>
              <!-- activiti 云支持 -->
              <dependency>
                  <groupId>org.activiti.cloud</groupId>
                  <artifactId>activiti-cloud-services-api</artifactId>
                  <version>${activiti.version}</version>
              </dependency>
              <!-- mysql驅(qū)動 -->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>5.1.40</version>
              </dependency>
              <!-- mybatis -->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.4.5</version>
              </dependency>
              <!-- 鏈接池 -->
              <dependency>
                  <groupId>commons-dbcp</groupId>
                  <artifactId>commons-dbcp</artifactId>
                  <version>1.4</version>
              </dependency>
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.12</version>
              </dependency>
              <!-- log start -->
              <dependency>
                  <groupId>log4j</groupId>
                  <artifactId>log4j</artifactId>
                  <version>${log4j.version}</version>
              </dependency>
              <dependency>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-api</artifactId>
                  <version>${slf4j.version}</version>
              </dependency>
              <dependency>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-log4j12</artifactId>
                  <version>${slf4j.version}</version>
              </dependency>
          </dependencies>
          • 添加log4j日志配置

          我們使用log4j日志包,可以對日志進行配置

          在resources 下創(chuàng)建log4j.properties

          # Set root category priority to INFO and its only appender to CONSOLE.
          #log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
          log4j.rootCategory=debug, CONSOLE, LOGFILE
          # Set the enterprise logger category to FATAL and its only appender to CONSOLE.
          log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
          # CONSOLE is set to be a ConsoleAppender using a PatternLayout.
          log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
          log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
          log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
          # LOGFILE is set to be a File appender using a PatternLayout.
          log4j.appender.LOGFILE=org.apache.log4j.FileAppender
          log4j.appender.LOGFILE.File=f:\act\activiti.log
          log4j.appender.LOGFILE.Append=true
          log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
          log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
          • 添加activiti配置文件

          我們使用activiti提供的默認方式來創(chuàng)建mysql的表。

          默認方式的要求是在 resources 下創(chuàng)建 activiti.cfg.xml 文件,注意:默認方式目錄和文件名不能修改,因為activiti的源碼中已經(jīng)設(shè)置,到固定的目錄讀取固定文件名的文件。

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:tx="http://www.springframework.org/schema/tx"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
                              http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/contex
          http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd"
          >

          </beans>
          • 在 activiti.cfg.xml 中進行配置

          默認方式要在在activiti.cfg.xml中bean的名字叫processEngineConfiguration,名字不可修改

          在這里有2中配置方式:一種是單獨配置數(shù)據(jù)源,一種是不單獨配置數(shù)據(jù)源

          1、直接配置processEngineConfiguration

          processEngineConfiguration 用來創(chuàng)建 ProcessEngine,在創(chuàng)建 ProcessEngine 時會執(zhí)行數(shù)據(jù)庫的操作。

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:context="http://www.springframework.org/schema/context"
                 xmlns:tx="http://www.springframework.org/schema/tx"
                 xsi:schemaLocation="http://www.springframework.org/schema/beans
                              http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/contex
          http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd"
          >

              <!-- 默認id對應(yīng)的值 為processEngineConfiguration -->
              <!-- processEngine Activiti的流程引擎 -->
              <bean id="processEngineConfiguration"
                    class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

                  <property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>
                  <property name="jdbcUrl" value="jdbc:mysql:///activiti"/>
                  <property name="jdbcUsername" value="root"/>
                  <property name="jdbcPassword" value="123456"/>
                  <!-- activiti數(shù)據(jù)庫表處理策略 -->
                  <property name="databaseSchemaUpdate" value="true"/>
              </bean>
          </beans>

          2、配置數(shù)據(jù)源后,在processEngineConfiguration 引用

          首先配置數(shù)據(jù)源

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:context="http://www.springframework.org/schema/context"
                 xmlns:tx="http://www.springframework.org/schema/tx"
                 xsi:schemaLocation="http://www.springframework.org/schema/beans
                              http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/contex
          http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd"
          >


              <!-- 這里可以使用 鏈接池 dbcp-->
              <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
                  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
                  <property name="url" value="jdbc:mysql:///activiti" />
                  <property name="username" value="root" />
                  <property name="password" value="123456" />
                  <property name="maxActive" value="3" />
                  <property name="maxIdle" value="1" />
              </bean>

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

                  <!-- 引用數(shù)據(jù)源 上面已經(jīng)設(shè)置好了-->
                  <property name="dataSource" ref="dataSource" />
                  <!-- activiti數(shù)據(jù)庫表處理策略 -->
                  <property name="databaseSchemaUpdate" value="true"/>
              </bean>
          </beans>
          • java類編寫程序生成表

          創(chuàng)建一個測試類,調(diào)用activiti的工具類,生成acitivti需要的數(shù)據(jù)庫表。

          直接使用activiti提供的工具類ProcessEngines,會默認讀取classpath下的activiti.cfg.xml文件,讀取其中的數(shù)據(jù)庫配置,創(chuàng)建 ProcessEngine,在創(chuàng)建ProcessEngine 時會自動創(chuàng)建表。

          代碼如下:

          package com.itheima.activiti01.test;

          import org.activiti.engine.ProcessEngine;
          import org.activiti.engine.ProcessEngineConfiguration;
          import org.junit.Test;

          public class TestDemo {
              /**
               * 生成 activiti的數(shù)據(jù)庫表
               */

              @Test
              public void testCreateDbTable() {
                  //使用classpath下的activiti.cfg.xml中的配置創(chuàng)建processEngine
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            System.out.println(processEngine);
              }
          }

          說明:

          • 運行以上程序段即可完成 activiti 表創(chuàng)建,通過改變 activiti.cfg.xmldatabaseSchemaUpdate 參數(shù)的值執(zhí)行不同的數(shù)據(jù)表處理策略。
          • 上 邊 的 方法 getDefaultProcessEngine方法在執(zhí)行時,從activiti.cfg.xml 中找固定的名稱 processEngineConfiguration

          在測試程序執(zhí)行過程中,idea的控制臺會輸出日志,說明程序正在創(chuàng)建數(shù)據(jù)表,類似如下,注意紅線內(nèi)容:

          執(zhí)行完成后我們查看數(shù)據(jù)庫, 創(chuàng)建了 25 張表,結(jié)果如下:

          到這,我們就完成activiti運行需要的數(shù)據(jù)庫和表的創(chuàng)建。

          3.4 表結(jié)構(gòu)介紹

          3.4.1 表的命名規(guī)則和作用

          看到剛才創(chuàng)建的表,我們發(fā)現(xiàn)Activiti 的表都以 ACT_ 開頭。

          第二部分是表示表的用途的兩個字母標識。用途也和服務(wù)的 API 對應(yīng)。

          • ACT_RE :'RE’表示 repository。這個前綴的表包含了流程定義和流程靜態(tài)資源 (圖片,規(guī)則,等等)。
          • ACT_RU:'RU’表示 runtime。這些運行時的表,包含流程實例,任務(wù),變量,異步任務(wù),等運行中的數(shù)據(jù)。Activiti 只在流程實例執(zhí)行過程中保存這些數(shù)據(jù), 在流程結(jié)束時就會刪除這些記錄。這樣運行時表可以一直很小速度很快。
          • ACT_HI:'HI’表示 history。這些表包含歷史數(shù)據(jù),比如歷史流程實例, 變量,任務(wù)等等。
          • ACT_GE :GE 表示 general。通用數(shù)據(jù), 用于不同場景下
          3.4.2 Activiti數(shù)據(jù)表介紹

          四、Activiti類關(guān)系圖

          上面我們完成了Activiti數(shù)據(jù)庫表的生成,java代碼中我們調(diào)用Activiti的工具類,下面來了解Activiti的類關(guān)系

          4.1 類關(guān)系圖

          在新版本中,我們通過實驗可以發(fā)現(xiàn)IdentityServiceFormService兩個Serivce都已經(jīng)刪除了。

          所以后面我們對于這兩個Service也不講解了,但老版本中還是有這兩個Service,同學(xué)們需要了解一下

          4.2 activiti.cfg.xml

          activiti的引擎配置文件,包括:ProcessEngineConfiguration的定義、數(shù)據(jù)源定義、事務(wù)管理器等,此文件其實就是一個spring配置文件。

          4.3 流程引擎配置類

          流程引擎的配置類(ProcessEngineConfiguration),通過ProcessEngineConfiguration可以創(chuàng)建工作流引擎ProceccEngine,常用的兩種方法如下:

          4.3.1 StandaloneProcessEngineConfiguration

          使用StandaloneProcessEngineConfigurationActiviti可以單獨運行,來創(chuàng)建ProcessEngineActiviti會自己處理事務(wù)。

          配置文件方式:

          通常在activiti.cfg.xml配置文件中定義一個id為 processEngineConfiguration 的bean。

          方法如下:

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

                  <!--配置數(shù)據(jù)庫相關(guān)的信息-->
                  <!--數(shù)據(jù)庫驅(qū)動-->
                  <property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>
                  <!--數(shù)據(jù)庫鏈接-->
                  <property name="jdbcUrl" value="jdbc:mysql:///activiti"/>
                  <!--數(shù)據(jù)庫用戶名-->
                  <property name="jdbcUsername" value="root"/>
                  <!--數(shù)據(jù)庫密碼-->
                  <property name="jdbcPassword" value="123456"/>
                  <!--actviti數(shù)據(jù)庫表在生成時的策略  true - 如果數(shù)據(jù)庫中已經(jīng)存在相應(yīng)的表,那么直接使用,如果不存在,那么會創(chuàng)建-->
                  <property name="databaseSchemaUpdate" value="true"/>
              </bean>

          還可以加入連接池:

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:context="http://www.springframework.org/schema/context"
                 xmlns:tx="http://www.springframework.org/schema/tx"
                 xsi:schemaLocation="http://www.springframework.org/schema/beans
                              http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/contex
          http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd"
          >

              <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
                  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
                  <property name="url" value="jdbc:mysql:///activiti"/>
                  <property name="username" value="root"/>
                  <property name="password" value="123456"/>
                  <property name="maxActive" value="3"/>
                  <property name="maxIdle" value="1"/>
              </bean>
              <!--在默認方式下 bean的id  固定為 processEngineConfiguration-->
              <bean id="processEngineConfiguration"
                    class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

                  <!--引入上面配置好的 鏈接池-->
                  <property name="dataSource" ref="dataSource"/>
                  <!--actviti數(shù)據(jù)庫表在生成時的策略  true - 如果數(shù)據(jù)庫中已經(jīng)存在相應(yīng)的表,那么直接使用,如果不存在,那么會創(chuàng)建-->
                  <property name="databaseSchemaUpdate" value="true"/>
              </bean>
          </beans>
          4.3.2 SpringProcessEngineConfiguration

          通過org.activiti.spring.SpringProcessEngineConfiguration 與Spring整合。

          創(chuàng)建spring與activiti的整合配置文件:

          activity-spring.cfg.xml(名稱可修改)

          <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
          xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
          xsi:schemaLocation="http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
                http://www.springframework.org/schema/mvc 
                http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
                http://www.springframework.org/schema/context 
                 http://www.springframework.org/schema/context/spring-context-3.1.xsd 
                http://www.springframework.org/schema/aop 
                http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
                http://www.springframework.org/schema/tx 
                http://www.springframework.org/schema/tx/spring-tx-3.1.xsd "
          >
             <!-- 工作流引擎配置bean -->
             <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
                <!-- 數(shù)據(jù)源 -->
                <property name="dataSource" ref="dataSource" />
                <!-- 使用spring事務(wù)管理器 -->
                <property name="transactionManager" ref="transactionManager" />
                <!-- 數(shù)據(jù)庫策略 -->
                <property name="databaseSchemaUpdate" value="drop-create" />
                <!-- activiti的定時任務(wù)關(guān)閉 -->
               <property name="jobExecutorActivate" value="false" />
             </bean>
             <!-- 流程引擎 -->
             <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
                <property name="processEngineConfiguration" ref="processEngineConfiguration" />
             </bean>
             <!-- 資源服務(wù)service -->
             <bean id="repositoryService" factory-bean="processEngine"
                factory-method="getRepositoryService" />
             <!-- 流程運行service -->
             <bean id="runtimeService" factory-bean="processEngine"
                factory-method="getRuntimeService" />
             <!-- 任務(wù)管理service -->
             <bean id="taskService" factory-bean="processEngine"
                factory-method="getTaskService" />
             <!-- 歷史管理service -->
             <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
             <!-- 用戶管理service -->
             <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
             <!-- 引擎管理service -->
             <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
             <!-- 數(shù)據(jù)源 -->
             <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
                <property name="driverClassName" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/activiti" />
                <property name="username" value="root" />
                <property name="password" value="mysql" />
                <property name="maxActive" value="3" />
                <property name="maxIdle" value="1" />
             </bean>
             <!-- 事務(wù)管理器 -->
             <bean id="transactionManager"
              class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource" />
             </bean>
             <!-- 通知 -->
             <tx:advice id="txAdvice" transaction-manager="transactionManager">
                <tx:attributes></tx:attributes>
                    <!-- 傳播行為 -->
                    <tx:method name="save*" propagation="REQUIRED" />
                    <tx:method name="insert*" propagation="REQUIRED" />
                    <tx:method name="delete*" propagation="REQUIRED" />
                    <tx:method name="update*" propagation="REQUIRED" />
                    <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
                    <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
                 </tx:attributes>
             </tx:advice>
             <!-- 切面,根據(jù)具體項目修改切點配置 -->
             <aop:config proxy-target-class="true">
                <aop:advisor advice-ref="txAdvice"  pointcut="execution(* com.itheima.ihrm.service.impl.*.(..))"* />
            </aop:config>
          </beans>

          創(chuàng)建processEngineConfiguration

          ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")

          上邊的代碼要求activiti.cfg.xml中必須有一個processEngineConfiguration的bean

          也可以使用下邊的方法,更改bean 的名字:

          ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource, String beanName);

          4.4 工作流引擎創(chuàng)建

          工作流引擎(ProcessEngine),相當(dāng)于一個門面接口,通過ProcessEngineConfiguration創(chuàng)建processEngine,通過ProcessEngine創(chuàng)建各個service接口。

          4.4.1 默認創(chuàng)建方式

          activiti.cfg.xml文件名及路徑固定,且activiti.cfg.xml文件中有 processEngineConfiguration的配置, 可以使用如下代碼創(chuàng)建processEngine:

          //直接使用工具類 ProcessEngines,使用classpath下的activiti.cfg.xml中的配置創(chuàng)建processEngine
          ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          System.out.println(processEngine);
          4.4.2 一般創(chuàng)建方式
          //先構(gòu)建ProcessEngineConfiguration
          ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
          //通過ProcessEngineConfiguration創(chuàng)建ProcessEngine,此時會創(chuàng)建數(shù)據(jù)庫
          ProcessEngine processEngine = configuration.buildProcessEngine();
          4.5 Servcie服務(wù)接口

          Service是工作流引擎提供用于進行工作流部署、執(zhí)行、管理的服務(wù)接口,我們使用這些接口可以就是操作服務(wù)對應(yīng)的數(shù)據(jù)表

          4.5.1 Service創(chuàng)建方式

          通過ProcessEngine創(chuàng)建Service

          方式如下:

          RuntimeService runtimeService = processEngine.getRuntimeService();
          RepositoryService repositoryService = processEngine.getRepositoryService();
          TaskService taskService = processEngine.getTaskService();

          4.5.2 Service總覽

          簡單介紹:

          • RepositoryService

          是activiti的資源管理類,提供了管理和控制流程發(fā)布包和流程定義的操作。使用工作流建模工具設(shè)計的業(yè)務(wù)流程圖需要使用此service將流程定義文件的內(nèi)容部署到計算機。

          除了部署流程定義以外還可以:查詢引擎中的發(fā)布包和流程定義。

          暫停或激活發(fā)布包,對應(yīng)全部和特定流程定義。暫停意味著它們不能再執(zhí)行任何操作了,激活是對應(yīng)的反向操作。獲得多種資源,像是包含在發(fā)布包里的文件, 或引擎自動生成的流程圖。

          獲得流程定義的pojo版本, 可以用來通過java解析流程,而不必通過xml。

          • RuntimeService

          Activiti的流程運行管理類。可以從這個服務(wù)類中獲取很多關(guān)于流程執(zhí)行相關(guān)的信息

          • TaskService

          Activiti的任務(wù)管理類。可以從這個類中獲取任務(wù)的信息。

          • HistoryService

          Activiti的歷史管理類,可以查詢歷史信息,執(zhí)行流程時,引擎會保存很多數(shù)據(jù)(根據(jù)配置),比如流程實例啟動時間,任務(wù)的參與者, 完成任務(wù)的時間,每個流程實例的執(zhí)行路徑,等等。這個服務(wù)主要通過查詢功能來獲得這些數(shù)據(jù)。

          • ManagementService

          Activiti的引擎管理類,提供了對 Activiti 流程引擎的管理和維護功能,這些功能不在工作流驅(qū)動的應(yīng)用程序中使用,主要用于 Activiti 系統(tǒng)的日常維護。

          五、Activiti入門

          在本章內(nèi)容中,我們來創(chuàng)建一個Activiti工作流,并啟動這個流程。

          創(chuàng)建Activiti工作流主要包含以下幾步:

          • 定義流程,按照BPMN的規(guī)范,使用流程定義工具,用流程符號把整個流程描述出來

          • 部署流程,把畫好的流程定義文件,加載到數(shù)據(jù)庫中,生成表的數(shù)據(jù)

          • 啟動流程,使用java代碼來操作數(shù)據(jù)庫表中的內(nèi)容

          5.1 流程符號

          BPMN 2.0是業(yè)務(wù)流程建模符號2.0的縮寫。

          它由Business Process Management Initiative這個非營利協(xié)會創(chuàng)建并不斷發(fā)展。作為一種標識,BPMN 2.0是使用一些符號來明確業(yè)務(wù)流程設(shè)計流程圖的一整套符號規(guī)范,它能增進業(yè)務(wù)建模時的溝通效率。

          目前BPMN2.0是最新的版本,它用于在BPM上下文中進行布局和可視化的溝通。

          接下來我們先來了解在流程設(shè)計中常見的 符號。

          BPMN2.0的基本符合主要包含:

          事件 Event
          活動 Activity

          活動是工作或任務(wù)的一個通用術(shù)語。一個活動可以是一個任務(wù),還可以是一個當(dāng)前流程的子處理流程;其次,你還可以為活動指定不同的類型。常見活動如下:

          網(wǎng)關(guān) GateWay

          網(wǎng)關(guān)用來處理決策,有幾種常用網(wǎng)關(guān)需要了解:

          排他網(wǎng)關(guān) (x)

          ——只有一條路徑會被選擇。流程執(zhí)行到該網(wǎng)關(guān)時,按照輸出流的順序逐個計算,當(dāng)條件的計算結(jié)果為true時,繼續(xù)執(zhí)行當(dāng)前網(wǎng)關(guān)的輸出流;

          • 如果多條線路計算結(jié)果都是 true,則會執(zhí)行第一個值為 true 的線路。如果所有網(wǎng)關(guān)計算結(jié)果沒有true,則引擎會拋出異常。

          • 排他網(wǎng)關(guān)需要和條件順序流結(jié)合使用,default 屬性指定默認順序流,當(dāng)所有的條件不滿足時會執(zhí)行默認順序流。

          并行網(wǎng)關(guān) (+)

          ——所有路徑會被同時選擇

          • 拆分 —— 并行執(zhí)行所有輸出順序流,為每一條順序流創(chuàng)建一個并行執(zhí)行線路。

          • 合并 —— 所有從并行網(wǎng)關(guān)拆分并執(zhí)行完成的線路均在此等候,直到所有的線路都執(zhí)行完成才繼續(xù)向下執(zhí)行。

          包容網(wǎng)關(guān) (+)

          —— 可以同時執(zhí)行多條線路,也可以在網(wǎng)關(guān)上設(shè)置條件

          • 拆分 —— 計算每條線路上的表達式,當(dāng)表達式計算結(jié)果為true時,創(chuàng)建一個并行線路并繼續(xù)執(zhí)行

          • 合并 —— 所有從并行網(wǎng)關(guān)拆分并執(zhí)行完成的線路均在此等候,直到所有的線路都執(zhí)行完成才繼續(xù)向下執(zhí)行。

          事件網(wǎng)關(guān) (+)

          —— 專門為中間捕獲事件設(shè)置的,允許設(shè)置多個輸出流指向多個不同的中間捕獲事件。當(dāng)流程執(zhí)行到事件網(wǎng)關(guān)后,流程處于等待狀態(tài),需要等待拋出事件才能將等待狀態(tài)轉(zhuǎn)換為活動狀態(tài)。

          流向 Flow

          流是連接兩個流程節(jié)點的連線。常見的流向包含以下幾種:

          5.2 流程設(shè)計器使用

          Activiti-Designer使用
          Palette(畫板)

          在idea中安裝插件即可使用,畫板中包括以下結(jié)點:

          • Connection—連接

          • Event—事件

          • Task—任務(wù)

          • Gateway—網(wǎng)關(guān)

          • Container—容器

          • Boundary event—邊界事件

          • Intermediate event- -中間事件

          流程圖設(shè)計完畢保存生成.bpmn文件

          新建流程(IDEA工具)

          首先選中存放圖形的目錄(選擇resources下的bpmn目錄),點擊菜單:New -> BpmnFile,如圖:

          彈出如下圖所示框,輸入evection 表示 出差審批流程:

          起完名字evection后(默認擴展名為bpmn),就可以看到流程設(shè)計頁面,如圖所示:

          左側(cè)區(qū)域是繪圖區(qū),右側(cè)區(qū)域是palette畫板區(qū)域

          鼠標先點擊畫板的元素即可在左側(cè)繪圖

          繪制流程

          使用滑板來繪制流程,通過從右側(cè)把圖標拖拽到左側(cè)的畫板,最終效果如下:

          指定流程定義Key

          流程定義key即流程定義的標識,通過properties視圖查看流程的key

          指定任務(wù)負責(zé)人

          在properties視圖指定每個任務(wù)結(jié)點的負責(zé)人,如:填寫出差申請的負責(zé)人為 zhangsan

          • 經(jīng)理審批負責(zé)人為 jerry

          • 總經(jīng)理審批負責(zé)人為 jack

          • 財務(wù)審批負責(zé)人為 rose

          六、流程操作

          6.1 流程定義

          概述

          流程定義是線下按照bpmn2.0標準去描述 業(yè)務(wù)流程,通常使用idea中的插件對業(yè)務(wù)流程進行建模。

          使用idea下的designer設(shè)計器繪制流程,并會生成兩個文件:.bpmn和.png

          .bpmn文件

          使用activiti-desinger設(shè)計業(yè)務(wù)流程,會生成.bpmn文件,上面我們已經(jīng)創(chuàng)建好了bpmn文件

          BPMN 2.0根節(jié)點是definitions節(jié)點。這個元素中,可以定義多個流程定義(不過我們建議每個文件只包含一個流程定義, 可以簡化開發(fā)過程中的維護難度)。

          注意,definitions元素 最少也要包含xmlns 和 targetNamespace的聲明。targetNamespace可以是任意值,它用來對流程實例進行分類。

          • 流程定義部分:定義了流程每個結(jié)點的描述及結(jié)點之間的流程流轉(zhuǎn)。

          • 流程布局定義:定義流程每個結(jié)點在流程圖上的位置坐標等信息。

          生成.png圖片文件

          IDEA工具中的操作方式

          1、修改文件后綴為xml

          首先將evection.bpmn文件改名為evection.xml,如下圖:

          evection.xml修改前的bpmn文件,效果如下:

          2、使用designer設(shè)計器打開.xml文件

          在evection.xml文件上面,點右鍵并選擇Diagrams菜單,再選擇Show BPMN2.0 Designer…

          3、查看打開的文件

          打開后,卻出現(xiàn)亂碼,如圖:

          4、解決中文亂碼

          1、打開Settings,找到File Encodings,把encoding的選項都選擇UTF-8

          2、打開IDEA安裝路徑,找到如下的安裝目錄

          根據(jù)自己所安裝的版本來決定,我使用的是64位的idea,所以在idea64.exe.vmoptions文件的最后一行追加一條命令: -Dfile.encoding=UTF-8

          如下所示:

          一定注意,不要有空格,否則重啟IDEA時會打不開,然后 重啟IDEA。

          如果以上方法已經(jīng)做完,還出現(xiàn)亂碼,就再修改一個文件,并在文件的末尾添加:-Dfile.encoding=UTF-8,然后重啟idea,如圖:

          最后重新在evection.xml文件上面,點右鍵并選擇Diagrams菜單,再選擇Show BPMN2.0 Designer…,看到生成圖片,如圖:

          到此,解決亂碼問題

          5、導(dǎo)出為圖片文件

          點擊Export To File的小圖標,打開如下窗口,注意填寫文件名及擴展名,選擇好保存圖片的位置:

          然后,我們把png文件拷貝到resources下的bpmn目錄,并且把evection.xml改名為evection.bpmn。

          6.2 流程定義部署

          概述

          將上面在設(shè)計器中定義的流程部署到activiti數(shù)據(jù)庫中,就是流程定義部署。

          通過調(diào)用activiti的api將流程定義的bpmn和png兩個文件一個一個添加部署到activiti中,也可以將兩個文件打成zip包進行部署。

          單個文件部署方式

          分別將bpmn文件和png圖片文件部署。

          public class ActivitiDemo {
              /**
               * 部署流程定義
               */

              @Test
              public void testDeployment(){
          //        1、創(chuàng)建ProcessEngine
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        2、得到RepositoryService實例
                  RepositoryService repositoryService = processEngine.getRepositoryService();
          //        3、使用RepositoryService進行部署
                  Deployment deployment = repositoryService.createDeployment()
                          .addClasspathResource("bpmn/evection.bpmn"// 添加bpmn資源
                          .addClasspathResource("bpmn/evection.png")  // 添加png資源
                          .name("出差申請流程")
                          .deploy();
          //        4、輸出部署信息
                  System.out.println("流程部署id:" + deployment.getId());
                  System.out.println("流程部署名稱:" + deployment.getName());
              }
          }

          執(zhí)行此操作后activiti會將上邊代碼中指定的bpm文件和圖片文件保存在activiti數(shù)據(jù)庫。

          壓縮包部署方式

          evection.bpmnevection.png壓縮成zip包。

          @Test
           public void deployProcessByZip() {
            // 定義zip輸入流
            InputStream inputStream = this
              .getClass()
              .getClassLoader()
              .getResourceAsStream(
                "bpmn/evection.zip");
            ZipInputStream zipInputStream = new ZipInputStream(inputStream);
            // 獲取repositoryService
            RepositoryService repositoryService = processEngine
              .getRepositoryService();
            // 流程部署
            Deployment deployment = repositoryService.createDeployment()
              .addZipInputStream(zipInputStream)
              .deploy();
            System.out.println("流程部署id:" + deployment.getId());
            System.out.println("流程部署名稱:" + deployment.getName());
           }

          執(zhí)行此操作后activiti會將上邊代碼中指定的bpm文件和圖片文件保存在activiti數(shù)據(jù)庫。

          操作數(shù)據(jù)表

          流程定義部署后操作activiti的3張表如下:

          • act_re_deployment 流程定義部署表,每部署一次增加一條記錄

          • act_re_procdef 流程定義表,部署每個新的流程定義都會在這張表中增加一條記錄

          • act_ge_bytearray 流程資源表

          接下來我們來看看,寫入了什么數(shù)據(jù):

          SELECT * FROM act_re_deployment #流程定義部署表,記錄流程部署信息

          結(jié)果:

          SELECT * FROM act_re_procdef #流程定義表,記錄流程定義信息

          結(jié)果:

          注意,KEY 這個字段是用來唯一識別不同流程的關(guān)鍵字

          SELECT * FROM act_ge_bytearray #資源表 

          結(jié)果:

          注意:

          act_re_deploymentact_re_procdef一對多關(guān)系,一次部署在流程部署表生成一條記錄,但一次部署可以部署多個流程定義,每個流程定義在流程定義表生成一條記錄。每一個流程定義在act_ge_bytearray會存在兩個資源記錄,bpmn和png。

          建議:一次部署一個流程,這樣部署表和流程定義表是一對一有關(guān)系,方便讀取流程部署及流程定義信息。

          6.3 啟動流程實例

          流程定義部署在activiti后就可以通過工作流管理業(yè)務(wù)流程了,也就是說上邊部署的出差申請流程可以使用了。

          針對該流程,啟動一個流程表示發(fā)起一個新的出差申請單,這就相當(dāng)于java類與java對象的關(guān)系,類定義好后需要new創(chuàng)建一個對象使用,當(dāng)然可以new多個對象。對于請出差申請流程,張三發(fā)起一個出差申請單需要啟動一個流程實例,出差申請單發(fā)起一個出差單也需要啟動一個流程實例。

          代碼如下:

              /**
               * 啟動流程實例
               */

              @Test
              public void testStartProcess(){
          //        1、創(chuàng)建ProcessEngine
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        2、獲取RunTimeService
                  RuntimeService runtimeService = processEngine.getRuntimeService();
          //        3、根據(jù)流程定義Id啟動流程
                  ProcessInstance processInstance = runtimeService
                          .startProcessInstanceByKey("myEvection");
          //        輸出內(nèi)容
                  System.out.println("流程定義id:" + processInstance.getProcessDefinitionId());
                  System.out.println("流程實例id:" + processInstance.getId());
                  System.out.println("當(dāng)前活動Id:" + processInstance.getActivityId());
              }

          輸出內(nèi)容如下:

          操作數(shù)據(jù)表

          • act_hi_actinst 流程實例執(zhí)行歷史

          • act_hi_identitylink 流程的參與用戶歷史信息

          • act_hi_procinst 流程實例歷史信息

          • act_hi_taskinst 流程任務(wù)歷史信息

          • act_ru_execution 流程執(zhí)行信息

          • act_ru_identitylink 流程的參與用戶信息

          • act_ru_task 任務(wù)信息

          6.4 任務(wù)查詢

          流程啟動后,任務(wù)的負責(zé)人就可以查詢自己當(dāng)前需要處理的任務(wù),查詢出來的任務(wù)都是該用戶的待辦任務(wù)。

          /**
               * 查詢當(dāng)前個人待執(zhí)行的任務(wù)
                */

              @Test
              public void testFindPersonalTaskList() {
          //        任務(wù)負責(zé)人
                  String assignee = "zhangsan";
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        創(chuàng)建TaskService
                  TaskService taskService = processEngine.getTaskService();
          //        根據(jù)流程key 和 任務(wù)負責(zé)人 查詢?nèi)蝿?wù)
                  List<Task> list = taskService.createTaskQuery()
                          .processDefinitionKey("myEvection"//流程Key
                          .taskAssignee(assignee)//只查詢該任務(wù)負責(zé)人的任務(wù)
                          .list();

                  for (Task task : list) {

                      System.out.println("流程實例id:" + task.getProcessInstanceId());
                      System.out.println("任務(wù)id:" + task.getId());
                      System.out.println("任務(wù)負責(zé)人:" + task.getAssignee());
                      System.out.println("任務(wù)名稱:" + task.getName());

                  }
              }

          輸出結(jié)果如下:

          流程實例id:2501
          任務(wù)id:2505
          任務(wù)負責(zé)人:zhangsan
          任務(wù)名稱:創(chuàng)建出差申請

          6.5 流程任務(wù)處理

          任務(wù)負責(zé)人查詢待辦任務(wù),選擇任務(wù)進行處理,完成任務(wù)。

          // 完成任務(wù)
              @Test
              public void completTask(){
          //        獲取引擎
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        獲取taskService
                  TaskService taskService = processEngine.getTaskService();

          //        根據(jù)流程key 和 任務(wù)的負責(zé)人 查詢?nèi)蝿?wù)
          //        返回一個任務(wù)對象
                  Task task = taskService.createTaskQuery()
                          .processDefinitionKey("myEvection"//流程Key
                          .taskAssignee("zhangsan")  //要查詢的負責(zé)人
                          .singleResult();

          //        完成任務(wù),參數(shù):任務(wù)id
                  taskService.complete(task.getId());
              }

          6.6 流程定義信息查詢

          查詢流程相關(guān)信息,包含流程定義,流程部署,流程定義版本

              /**
               * 查詢流程定義
               */

              @Test
              public void queryProcessDefinition(){
                  //        獲取引擎
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        repositoryService
                  RepositoryService repositoryService = processEngine.getRepositoryService();
          //        得到ProcessDefinitionQuery 對象
                  ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
          //          查詢出當(dāng)前所有的流程定義
          //          條件:processDefinitionKey =evection
          //          orderByProcessDefinitionVersion 按照版本排序
          //        desc倒敘
          //        list 返回集合
                  List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("myEvection")
                          .orderByProcessDefinitionVersion()
                          .desc()
                          .list();
          //      輸出流程定義信息
                  for (ProcessDefinition processDefinition : definitionList) {
                      System.out.println("流程定義 id="+processDefinition.getId());
                      System.out.println("流程定義 name="+processDefinition.getName());
                      System.out.println("流程定義 key="+processDefinition.getKey());
                      System.out.println("流程定義 Version="+processDefinition.getVersion());
                      System.out.println("流程部署ID ="+processDefinition.getDeploymentId());
                  }

              }

          輸出結(jié)果:

          流程定義id:myEvection:1:4
          流程定義名稱:出差申請單
          流程定義key:myEvection
          流程定義版本:1

          6.7 流程刪除

          public void deleteDeployment() {
            // 流程部署id
            String deploymentId = "1";
            
              ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
              // 通過流程引擎獲取repositoryService
            RepositoryService repositoryService = processEngine
              .getRepositoryService();
            //刪除流程定義,如果該流程定義已有流程實例啟動則刪除時出錯
            repositoryService.deleteDeployment(deploymentId);
            //設(shè)置true 級聯(lián)刪除流程定義,即使該流程有流程實例啟動也可以刪除,設(shè)置為false非級別刪除方式,如果流程
            //repositoryService.deleteDeployment(deploymentId, true);
           }

          說明:

          • 使用repositoryService刪除流程定義,歷史表信息不會被刪除

          • 如果該流程定義下沒有正在運行的流程,則可以用普通刪除。

          如果該流程定義下存在已經(jīng)運行的流程,使用普通刪除報錯,可用級聯(lián)刪除方法將流程及相關(guān)記錄全部刪除。

          先刪除沒有完成流程節(jié)點,最后就可以完全刪除流程定義信息

          項目開發(fā)中級聯(lián)刪除操作一般只開放給超級管理員使用.

          6.8 流程資源下載

          現(xiàn)在我們的流程資源文件已經(jīng)上傳到數(shù)據(jù)庫了,如果其他用戶想要查看這些資源文件,可以從數(shù)據(jù)庫中把資源文件下載到本地。

          解決方案有:

          • jdbc對blob類型,clob類型數(shù)據(jù)讀取出來,保存到文件目錄

          • 使用activiti的api來實現(xiàn)

          使用commons-io.jar 解決IO的操作

          引入commons-io依賴包

          <dependency>
              <groupId>commons-io</groupId>
              <artifactId>commons-io</artifactId>
              <version>2.6</version>
          </dependency>

          通過流程定義對象獲取流程定義資源,獲取bpmn和png

          import org.apache.commons.io.IOUtils;

          @Test
              public void deleteDeployment(){
          //        獲取引擎
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        獲取repositoryService
                  RepositoryService repositoryService = processEngine.getRepositoryService();
          //        根據(jù)部署id 刪除部署信息,如果想要級聯(lián)刪除,可以添加第二個參數(shù),true
                  repositoryService.deleteDeployment("1");
              }

              public void  queryBpmnFile() throws IOException {
          //        1、得到引擎
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        2、獲取repositoryService
                  RepositoryService repositoryService = processEngine.getRepositoryService();
          //        3、得到查詢器:ProcessDefinitionQuery,設(shè)置查詢條件,得到想要的流程定義
                  ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                          .processDefinitionKey("myEvection")
                          .singleResult();
          //        4、通過流程定義信息,得到部署ID
                  String deploymentId = processDefinition.getDeploymentId();
          //        5、通過repositoryService的方法,實現(xiàn)讀取圖片信息和bpmn信息
          //        png圖片的流
                  InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
          //        bpmn文件的流
                  InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
          //        6、構(gòu)造OutputStream流
                  File file_png = new File("d:/evectionflow01.png");
                  File file_bpmn = new File("d:/evectionflow01.bpmn");
                  FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
                  FileOutputStream pngOut = new FileOutputStream(file_png);
          //        7、輸入流,輸出流的轉(zhuǎn)換
                  IOUtils.copy(pngInput,pngOut);
                  IOUtils.copy(bpmnInput,bpmnOut);
          //        8、關(guān)閉流
                  pngOut.close();
                  bpmnOut.close();
                  pngInput.close();
                  bpmnInput.close();
              }

          說明:

          • deploymentId為流程部署ID
          • resource_nameact_ge_bytearray表中NAME_列的值
          • 使用repositoryServicegetDeploymentResourceNames方法可以獲取指定部署下得所有文件的名稱
          • 使用repositoryServicegetResourceAsStream方法傳入部署ID和資源圖片名稱可以獲取部署下指定名稱文件的輸入流

          最后的將輸入流中的圖片資源進行輸出。

          6.9 流程歷史信息的查看

          即使流程定義已經(jīng)刪除了,流程執(zhí)行的歷史信息通過前面的分析,依然保存在activiti的act_hi_*相關(guān)的表中。所以我們還是可以查詢流程執(zhí)行的歷史信息,可以通過HistoryService來查看相關(guān)的歷史記錄。

              /**
               * 查看歷史信息
               */

              @Test
              public void findHistoryInfo(){
          //      獲取引擎
                  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
          //        獲取HistoryService
                  HistoryService historyService = processEngine.getHistoryService();
          //        獲取 actinst表的查詢對象
                  HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
          //        查詢 actinst表,條件:根據(jù) InstanceId 查詢
          //        instanceQuery.processInstanceId("2501");
          //        查詢 actinst表,條件:根據(jù) DefinitionId 查詢
                  instanceQuery.processDefinitionId("myEvection:1:4");
          //        增加排序操作,orderByHistoricActivityInstanceStartTime 根據(jù)開始時間排序 asc 升序
                  instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
          //        查詢所有內(nèi)容
                  List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
          //        輸出
                  for (HistoricActivityInstance hi : activityInstanceList) {
                      System.out.println(hi.getActivityId());
                      System.out.println(hi.getActivityName());
                      System.out.println(hi.getProcessDefinitionId());
                      System.out.println(hi.getProcessInstanceId());
                      System.out.println("<==========================>");
                  }
              }

          總結(jié)

          基本功能介紹以及完成了,如果還需要更加高級的功能比如掛起、激活流程實例、流程變量等請參考

          • https://andyoung.blog.csdn.net/article/details/118345330

          工作流引擎 Activiti 與 Spring boot 結(jié)合會是開發(fā)跟簡單,不如來看下

          • https://andyoung.blog.csdn.net/article/details/118372175

          來源:https://blog.csdn.net/agonie201218/

          article/details/118198535


          到此文章就結(jié)束了。Java架構(gòu)師必看一個集公眾號、小程序、網(wǎng)站(3合1的文章平臺,給您架構(gòu)路上一臂之力,javajgs.com)。如果今天的文章對你在進階架構(gòu)師的路上有新的啟發(fā)和進步,歡迎轉(zhuǎn)發(fā)給更多人。歡迎加入架構(gòu)師社區(qū)技術(shù)交流群,眾多大咖帶你進階架構(gòu)師,在后臺回復(fù)“加群”即可入群。



          這些年小編給你分享過的干貨


          1.idea永久激活碼(親測可用)

          2.優(yōu)質(zhì)ERP系統(tǒng)帶進銷存財務(wù)生產(chǎn)功能(附源碼)

          3.優(yōu)質(zhì)SpringBoot帶工作流管理項目(附源碼)

          4.最好用的OA系統(tǒng),拿來即用(附源碼)

          5.SBoot+Vue外賣系統(tǒng)前后端都有(附源碼

          6.SBoot+Vue可視化大屏拖拽項目(附源碼)


          轉(zhuǎn)發(fā)在看就是最大的支持??

          瀏覽 54
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕亚洲一区 | 亚洲欧洲小视频 | 97超碰自拍 | 中文无码99 | 翔田千里vs黑人播放 |