天天看點

Activiti工作流入門

1.什麼是工作流

(1)工作流介紹

工作流(workflow),就是通過計算機對業務流程自動化執行管理。它主要解決的是"使在多個參與者之間按照某種預定義的規則自動進行傳遞文檔、資訊或任務的過程,進而實作某個預期的業務目标"。

(2)實作方式

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

針對有權限可以檢視的記錄,目前使用者根據自己的角色來決定審批是否合格的操作。如果合格将狀态字段設定一個值,來代表合格;當然如果不合格也需要設定一個值來代表不合格的情況。

這是一種最為原始的方式。通過狀态字段雖然做到了流程控制,但是當我們的流程發生變更的時候, 這種方式所編寫的代碼也要進行調整。

那麼有沒有專業的方式來實作工作流的管理呢?并且可以做到業務流程變化之後,我們的程式可以不用改變,如果可以實作這樣的效果,那麼我們的業務系統的适應能力就得到了極大提升。

2.activiti

Activiti 是一個工作流引擎, activiti 可以将業務系統中複雜的業務流程抽取出來,使用專門的模組化語言(BPMN2.0)進行定義,業務系統按照預先定義的流程進行執行,實作了業務系統的業務流程由 activiti 進行管理,減少業務系統由于流程變更進行系統更新改造的工作量,進而提高系統的健壯性,同時也減少了系統開發維護成本。

官方網站:https://www.activiti.org/

(1)什麼是BPMN

BPMN(Business Process Model And Notation)業務流程模型和符号 是由 BPMI(BusinessProcess Management Initiative)開發的一套标準的業務流程模組化符号,使用 BPMN 提供的符号可以建立業務流程。 2004 年 5 月釋出了 BPMN1.0 規範。BPMI 于 2005 年 9 月并入 OMG(The Object Management Group 對象管理組織)組織。OMG 于 2011 年 1 月釋出 BPMN2.0 的最終版本。

BPMN 是目前被各 BPM 廠商廣泛接受的 BPM 标準。Activiti 就是使用 BPMN 2.0 進行流程模組化、流程執行管理,它包括很多的模組化符号。

Activiti工作流入門

一個 bpmn 圖形的例子: 首先當事人發起一個請假單; 其次他所在部門的經理對請假單進行稽核; 然後人事經理進行複核并進行備案; 最後請假流程結束。

Activiti工作流入門

Bpmn 圖形其實是通過 xml 表示業務流程。通過将bpmn流程圖字尾修改為xml,可以看到具體内容。

(2)Activiti支援的資料庫

Activiti工作流入門

3.在java中使用activiti

本次使用activiti7+IDEA開發工具

注:activiti7需要安裝actiBPM插件

(1)建立資料庫

CREATE DATABASE activiti DEFAULT CHARACTER SET utf8;
           

(2)導入依賴

建立maven項目,導入相關依賴

Activiti工作流入門

pom.xml

 <properties>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
    </properties>
​
    <dependencies>
​
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>
​
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>
​
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-model</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>
​
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-converter</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>
​
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>
​
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-layout</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>
​
        <dependency>
            <groupId>org.activiti.cloud</groupId>
            <artifactId>activiti-cloud-services-api</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>
​
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</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>
        <!-- log end -->
​
        <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>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.0</version>
        </dependency>
    </dependencies>
           

(3)配置檔案

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
​
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=/Users/apple/學習/study/activity/activity_01/xis.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
           

activiti.cfg.xml

<?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://localhost:3306/activiti" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>
    <!-- activiti單獨運作的ProcessEngine配置對象(processEngineConfiguration),使用單獨啟動方式
        預設情況下:bean的id=processEngineConfiguration
    -->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <!-- 代表資料源 -->
    <property name="dataSource" ref="dataSource"></property>
​
    <!-- 如果不使用上面的bean配置資料源,也可以使用如下方法配置資料源 -->
   <!-- <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti" />
    <property name="jdbcUsername" value="root" />
    <property name="jdbcPassword" value="root" />
   -->
​
    <!-- 代表是否生成表結構 -->
    <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
           

databaseSchemaUpdate參數:

false(預設):檢查資料庫表的版本和依賴庫的版本, 如果版本不比對就抛出異常。

true: 建構流程引擎時,執行檢查,如果需要就執行更新。 如果表不存在,就建立。

create-drop: 建構流程引擎時建立資料庫表, 關閉流程引擎時删除這些表。

drop-create:先删除表再建立表。

create: 建構流程引擎時建立資料庫表, 關閉流程引擎時不删除這些表。

(4)編寫測試代碼

ActivitiTest.java

/**
 * 測試類:
 * 測試所需要的activiti的25張表的生成
 */
public class ActivitiTest {
​
    @Test
    public void testGenTable() {
        //1.建立ProcessEngineConfiguration對象
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        //2.建立ProcessEngine對象
        ProcessEngine processEngine = configuration.buildProcessEngine();
        System.out.println(processEngine);
    }
​
    @Test
    public void testGenTable2() {
        //使用下面這種方式生成表的條件
        //1.activiti配置檔案名稱必須為activiti.cfg.xml
        //2.bean的id必須為"processEngineConfiguration"
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(defaultProcessEngine);
    }
​
}
           

運作完代碼之後可以發現配置的資料庫中生成了25張表。

4.activiti詳解

(1)資料庫

Activiti工作流入門

資料庫表的命名規則:

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

  • ACT_RE_*: 'RE'表示 repository。 這個字首的表包含了流程定義和流程靜态資源 (圖檔, 規則,等等)。
  • ACT_RU_*: 'RU'表示 runtime。 這些運作時的表,包含流程執行個體,任務,變量,異步任務, 等運作中的資料。 Activiti 隻在流程執行個體執行過程中儲存這些資料, 在流程結束時就會删除這些記錄。 這樣運作時表可以一直很小速度很快。
  • ACT_HI_*: 'HI'表示 history。 這些表包含曆史資料,比如曆史流程執行個體, 變量,任務等。
  • ACT_GE_*: GE 表示 general。通用資料, 用于不同場景下。

(2)activiti.cfg.xml

activiti 的引擎配置檔案,包括:ProcessEngineConfiguration 的定義、資料源定義、事務管理器等,此檔案其實就是一個 spring 配置檔案。

(3)ProcessEngineConfiguration

流程引擎的配置類,通過 ProcessEngineConfiguration 可以建立工作流引擎 ProceccEngine。

(4)ProcessEngine

工作流引擎,相當于一個門面接口,通過 ProcessEngineConfiguration 建立 processEngine,通過ProcessEngine 建立各個 service 接口。

(5)Service

通過 ProcessEngine 建立 Service,Service 是工作流引擎提供用于進行工作流部署、執行、管理的服務接口。

  • RepositoryService

是 activiti 的資源管理類,提供了管理和控制流程釋出包和流程定義的操作。使用工作流模組化工具設計的業務流程圖需要使用此 service 将流程定義檔案的内容部署到計算機。

除了部署流程定義以外還可以:

查詢引擎中的釋出包和流程定義。

暫停或激活釋出包,對應全部和特定流程定義。 暫停意味着它們不能再執行任何操作了,激活是對應的反向操作。

獲得多種資源,像是包含在釋出包裡的檔案, 或引擎自動生成的流程圖。 獲得流程定義的pojo版本,可以用來通過 java 解析流程,而不必通過 xml。

  • RuntimeService

它是 activiti 的流程運作管理類。可以從這個服務類中擷取很多關于流程執行相關的資訊

  • TaskService

是 activiti 的任務管理類。可以從這個類中擷取任務的資訊。

  • HistoryService

是 activiti 的曆史管理類,可以查詢曆史資訊,執行流程時,引擎會儲存很多資料(根據配置),比如流程執行個體啟動時間,任務的參與者, 完成任務的時間,每個流程執行個體的執行路徑,等等。 這個服務主要通過查詢功能來獲得這些資料。

  • ManagementService

是activiti的引擎管理類,提供了對 Activiti 流程引擎的管理和維護功能,這些功能不在工作流驅動的應用程式中使用,主要用于 Activiti 系統的日常維護。