Activiti工做流引擎初學教程

http://wenku.baidu.com/view/bb7364ad4693daef5ff73d32.htmlhtml

1. 初識Activiti

1.1. 工做流與工做流引擎

工做流(workflow)就是工做流程的計算模型,即將工做流程中的工做如何先後組織在一塊兒的邏輯和規則在計算機中以恰當的模型進行表示並對其實施計算。它主要解決的是「使在多個參與者之間按照某種預約義的規則傳遞文檔、信息或任務的過程自動進行,從而實現某個預期的業務目標,或者促使此目標的實現」。(個人理解就是:將部分或者所有的工做流程、邏輯讓計算機幫你來處理,實現自動化)java

所謂工做流引擎是指workflow做爲應用系統的一部分,併爲之提供對各應用系統有決定做用的根據角色、分工和條件的不一樣決定信息傳遞路由、內容等級等核心解決方案。mysql

例如開發一個系統最關鍵的部分不是系統的界面,也不是和數據庫之間的信息交換,而是如何根據業務邏輯開發出符合實際須要的程序邏輯並確保其穩定性、易維護性和彈性。web

好比你的系統中有一個任務流程,通常狀況下這個任務的代碼邏輯、流程你都要本身來編寫。實現它是沒有問題的。可是誰能保證邏輯編寫的毫無紕漏?通過無數次的測試與改進,這個流程沒有任何漏洞也是能夠實現的,可是明顯就會拖慢整個項目的進度。spring

 工做流引擎解決的就是這個問題:若是應用程序缺少強大的邏輯層,勢必變得容易出錯(信息的路由錯誤、死循環等等)。sql

1.2. BPMN2.0規範

BPMN(Business Process Model and Notation)--業務流程模型與符號。數據庫

BPMN是一套流程建模的標準,主要目標是被全部業務用戶容易理解的符號,支持從建立流程輪廓的業務分析到這些流程的最終實現,知道最終用戶的管理監控。apache

通俗一點其實就是一套規範,畫流程模型的規範。流程模型包括:流程圖、協做圖、編排圖、會話圖。詳細信息請google。api

1.3. Activiti概述

1.3.1. Activiti由來

學習過Activiti的朋友都知道,Activiti的創始人也就是JBPM(也是一個優秀的BPM引擎)的創始人,從Jboss離職後開發了一個新的BPM引擎:Activiti。因此,Activiti有不少地方都有JBPM的影子。因此,聽說學習過JBPM的朋友學起Activiti來很是順手。tomcat

因爲本人以前沒有工做流及JBPM的相關基礎,剛開始學習Activiti的時候能夠說是無比痛苦的,根本不知道從何下手,這裏也建議你們先進行工做流及BPMN2.0規範的學習,有了必定的基礎後,再着手學習Activiti。

1.3.2. Activiti簡介

Activiti是一個開源的工做流引擎,它實現了BPMN 2.0規範,能夠發佈設計好的流程定義,並經過api進行流程調度。

Activiti 做爲一個聽從 Apache 許可的工做流和業務流程管理開源平臺,其核心是基於 Java 的超快速、超穩定的 BPMN2.0 流程引擎,強調流程服務的可嵌入性和可擴展性,同時更增強調面向業務人員。

Activiti 流程引擎重點關注在系統開發的易用性和輕量性上。每一項 BPM 業務功能 Activiti 流程引擎都以服務的形式提供給開發人員。經過使用這些服務,開發人員可以構建出功能豐富、輕便且高效的 BPM 應用程序。

1.4. 文檔說明

以上部分對工做流、BPMN、Activiti的概念作了一個簡單的介紹,目的是瞭解Activiti到底是什麼,能作些什麼…及在學習Activiti以前須要瞭解的知識與技術。其中大部分文字來自Copy網上的各類資料與文檔,經過總結而來的。具體的更詳細的內容需本身google,參考一些官方的文檔與手冊。

本文檔以後內容以下:

1)      下載與使用

2)      核心組件與說明

3)      入門示例

4)      Eclipse中的Activiti插件的使用

本文檔旨在爲初學Activiti的朋友提供入門級別的參考,不會對其原理及其結構進行深層次的探究(更可能是由於目前自身理解還不是很透徹),只是爲你們理清思路,方便之後更深層次的學習。本文檔還有一個重要的特色,那就是根據本身看官方手冊的經驗,教你們如何看手冊從而更有效率!因爲是初學,不少術語或解釋不免理解有誤差,因此必定要看官方提供的文檔與手冊,那纔是學習的最佳途徑!

2. 開始學習

2.1. 必要的準備

2.1.1. 下載與瞭解目錄

下載Activiti:下載路徑,也就是官方網站的地址:http://activiti.org/download.html。下載後解壓(我所使用的是5.12版本的,Activiti更新速度飛快,幾乎每兩個月就會有一個更新的小版本),看到以下目錄:

1)      database:裏面存放的是Activiti使用到的數據庫信息的sql文件,它支持的數據庫類型以下圖,使用時只需執行你本身的數據庫類型的文件便可。如:你的數據庫是mysql,那麼就執行activiti.mysql.create.*.sql便可。

2)      docs:毫無疑問,api文檔是也。

3)      libs:使用Activiti所須要的全部的jar包和源文件。

4)      wars:官方給咱們提供的示例Demo,經過使用Demo能夠更加快速的瞭解Activiti。

2.1.2. 其餘準備

使用Activiti,首先固然要有jdk了!6+版本就能夠了。其次,要有一款IDE,咱們固然會使用Eclipse,這裏使用Juno版本。而後,web容器固然也要有,這裏使用Tomcat6.0版本。而後就是Activiti的Eclipse插件了,這個後面再介紹。

2.1.3. 一分鐘入門(見用戶手冊)

所謂的一分鐘入門就是經過運行你下載的包裏的wars文件夾裏的activiti-explorer.war文件,以便更快的瞭解Activiti。將文件拷貝至Tomcat的webapps目錄,啓動tomcat,輸入http://localhost:8080/activiti-explorer。而後你就能夠開整了!總算是有一點微小的進展了。

這裏須要說明的就是,這個Demo默認採用的是h2內存數據庫,若是想用你本身的數據庫,就須要修改web應用WEB-INF/classes目錄下的db.properties。而後,按上面說的,把database裏的create文件夾裏的數據庫文件導入你本身的數據庫(若是沒有修改db.properties,就不用導入了)。

Demo的具體解釋與數據庫配置的具體信息詳見官方手冊,手冊已經說的很清楚了。這裏須要重點了解activiti.cfg.xml的配置以及如何構建ProcessEngine(配置文件構建方式、代碼構建方式)。

對Demo的使用介紹在官方文檔的後面纔開始介紹,這裏建議應用跑起來以後,先本身試試手(可看後面介紹Demo如何使用的章節),看看如何跑一個流程、整個流程是怎麼流的、並隨時關注數據庫表裏的數據的變化等,對之後的學習頗有幫助!

2.2. 核心組件介紹

2.2.1. 關鍵對象

1.      Deployment:流程部署對象,部署一個流程時建立。

2.      ProcessDefinitions:流程定義,部署成功後自動建立。

3.      ProcessInstances:流程實例,啓動流程時建立。 

4.      Task:任務,在Activiti中的Task僅指有角色參與的任務,即定義中的UserTask。 

5.      Execution:執行計劃,流程實例和流程執行中的全部節點都是Execution,如UserTask、ServiceTask等。

2.2.2. 服務接口

1.      ProcessEngine:流程引擎的抽象,經過它咱們能夠得到咱們須要的一切服務。 

2.      RepositoryService:Activiti中每個不一樣版本的業務流程的定義都須要使用一些定義文件,部署文件和支持數據(例如BPMN2.0 XML文件,表單定義文件,流程定義圖像文件等),這些文件都存儲在Activiti內建的Repository中。RepositoryService提供了對 repository的存取服務。

3.      RuntimeService:在Activiti中,每當一個流程定義被啓動一次以後,都會生成一個相應的流程對象實例。RuntimeService提供了啓動流程、查詢流程實例、設置獲取流程實例變量等功能。此外它還提供了對流程部署,流程定義和流程實例的存取服務。

4.      TaskService: 在Activiti中業務流程定義中的每個執行節點被稱爲一個Task,對流程中的數據存取,狀態變動等操做均須要在Task中完成。TaskService提供了對用戶Task 和Form相關的操做。它提供了運行時任務查詢、領取、完成、刪除以及變量設置等功能。 

5.      IdentityService: Activiti中內置了用戶以及組管理的功能,必須使用這些用戶和組的信息才能獲取到相應的Task。IdentityService提供了對Activiti 系統中的用戶和組的管理功能。

6.      ManagementService: ManagementService提供了對Activiti流程引擎的管理和維護功能,這些功能不在工做流驅動的應用程序中使用,主要用於Activiti系統的平常維護。 

7.      HistoryService: HistoryService用於獲取正在運行或已經完成的流程實例的信息,與RuntimeService中獲取的流程信息不一樣,歷史信息包含已經持久化存儲的永久信息,並已經被針對查詢優化。

如今至少要知道有這些對象和接口。並結合Activiti Api這一章節來看,你就會對部署流程、啓動流程、執行任務等操做有一個基本的概念。以後編寫一個簡單的單元測試,主要爲了測試activiti.cfg.xml配置的是否正確,流程是否能夠被部署便可。

至於與Spring的集成,必定要熟悉基於Spring配置Activiti,以及事務的處理。

 

3. 入門示例(參考手冊中10分鐘教程)

3.1. 概述

下面開始編寫一個示例。這個Demo爲一個「月度報表申請」流程。由「sales(銷售)」組的用戶製做月度報表,提交給「management(經理)」組的用戶,經理審批該報表,最後結束。流程圖以下:

這個Demo完成以後,咱們會進行兩個測試。一個是代碼中的單元測試,就是跑一遍流程,看一下流程在跑的過程當中輸出的信息;一個是咱們將編輯好的bpmn20.xml文件經過咱們以前一分鐘入門的示例activiti-explorer應用導入進去,查看它的流程圖,並完整執行一遍流程。

在編寫這個Demo以前,至少要了解Activiti與Spring如何集成、XxxService各自的任務與做用,並完成上一章的Demo。

3.2. 流程文件xxx.bpmn20.xml

首先,咱們就來編寫這個流程的bpmn20.xml文件。

<definitions id="definitions"
  targetNamespace="http://activiti.org/bpmn20"
  xmlns:activiti="http://activiti.org/bpmn"
  xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">

        <process id="financialReport" name="Monthly financial report reminderprocess">

          <startEvent id="theStart" />

          <sequenceFlow id='flow1' sourceRef='theStart' targetRef='writeReportTask' />


          <userTask id="writeReportTask" name="Write monthly financial report" >
            <documentation>
              Write monthly financial reportfor publication to shareholders.
            </documentation>
            <potentialOwner>
              <resourceAssignmentExpression>
                <formalExpression>sales</formalExpression>
              </resourceAssignmentExpression>
            </potentialOwner>
          </userTask>

          <sequenceFlow id='flow2' sourceRef='writeReportTask' targetRef='verifyReportTask' />

          <userTask id="verifyReportTask" name="Verify monthly financial report" >
            <documentation>
              Verify monthly financial reportcomposed by the accountancy department.
              This financial report is goingto be sent to all the company shareholders.
            </documentation>
            <potentialOwner>
              <resourceAssignmentExpression>
                <formalExpression>management</formalExpression>
              </resourceAssignmentExpression>
            </potentialOwner>
          </userTask>

          <sequenceFlow id='flow3' sourceRef='verifyReportTask' targetRef='theEnd' />

          <endEvent id="theEnd" />

        </process>

</definitions>

這裏對部分代碼進行解釋。

1)       文件的開頭部分,這裏的id對於Activiti來講, 應該叫作key。建立流程實例時,會根據此id來獲得這個流程。

2)      開始流程。

3)      順序流(就是鏈接各個節點的指向線)

sourceRef和targetRef分別爲起始節點和目標節點。

4)      描述用戶任務

id爲該用戶任務的標識。

documentation爲該用戶任務的描述。

5)      分配用戶

能夠把任務分配給指定的用戶,也能夠分配給指定的組,而且能夠有多個,詳見用戶手冊。

3.3. Spring配置文件

這裏配置了數據源、事務管理、流程引擎及幾個必要的xxxService。這裏數據源使用的是dbcp。數據庫信息就配置成你本身本地數據庫的信息,若是不會配置。

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

         destroy-method="close">

         <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"/>

         <property name="initialSize" value="20" />

         <property name="maxActive" value="50"/>

         <property name="maxIdle" value="20"/>

         <property name="minIdle" value="10"/>

    </bean>


    <bean id="transactionManager"

         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

         <property name="dataSource" ref="dataSource"></property>

    </bean>

    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">

         <property name="dataSource" ref="dataSource" />

         <property name="transactionManager" ref="transactionManager" />

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

         <property name="jobExecutorActivate" value="false" />

    </bean>


    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">

         <property name="processEngineConfiguration" ref="processEngineConfiguration" />

    </bean>


    <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="managementService" factory-bean="processEngine"

         factory-method="getManagementService" />


    <tx:annotation-driven transaction-manager="transactionManager" />

注:bpmn20.xml文件中用到了兩個用戶組(sales、management),是由於咱們啓動Tomcat運行activiti-explorer應用初始化時自動就會往數據庫裏添加一些數據,其中用戶組的表中就會添加幾條記錄,其中就包括這兩個組,因此不用管它怎麼來的,總之數據庫裏有這兩個組就對了。而應用默認使用的是內存數據庫,服務一中止數據也就沒有了。因此爲了進行單元測試,須要按前面講的修改數據庫配置的方法:

把activiti-explorer應用的數據庫配置改爲你本身的本地數據庫的信息,我使用的是Mysql數據庫。再啓動tomcat運行應用(目的就是爲了讓數據庫有數據),這時你的本地數據庫就有數據了,能夠編寫測試用例進行單元測試了。

3.4. 編寫測試用例

1)      讀取Spring配置文件,注入流程所需的Service

2)      編寫測試方法

   @Test

    public void monthtest() {

        // 部署流程定義

        repositoryService.createDeployment().addClasspathResource("myProcess.bpmn20.xml").deploy();

        // 啓動流程實例

        String procId = runtimeService.startProcessInstanceByKey("financialReport").getId();

        // 得到第一個任務

        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("sales").list();

        for (Task task : tasks) {

            System.out.println("Following task is available for sales group: " + task.getName());

            // 認領任務這裏由foozie認領,由於fozzie是sales組的成員

            taskService.claim(task.getId(), "fozzie");

        }

        // 查看fozzie如今是否可以獲取到該任務

        tasks = taskService.createTaskQuery().taskAssignee("fozzie").list();

        for (Task task : tasks) {

            System.out.println("Task for fozzie: " + task.getName());

            // 執行(完成)任務

            taskService.complete(task.getId());

        }

        // 如今fozzie的可執行任務數就爲0了

        System.out.println("Number of tasks for fozzie: "

                           + taskService.createTaskQuery().taskAssignee("fozzie").count());

        // 得到第二個任務

        tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();

        for (Task task : tasks) {

            System.out.println("Following task is available for accountancy group:" + task.getName());

            // 認領任務這裏由kermit認領,由於kermit是management組的成員

            taskService.claim(task.getId(), "kermit");

        }

        // 完成第二個任務結束流程

        for (Task task : tasks) {

            taskService.complete(task.getId());

        }

        // 覈實流程是否結束,輸出流程結束時間

        HistoricProcessInstancehistoricProcessInstance = historyService.createHistoricProcessInstanceQuery()

                                                                       .processInstanceId(procId).singleResult();

        System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());

}

3)  運行示例,Demo完成。這就是一個最簡單的流程,經過這個流程,瞭解到Activiti中流程是怎麼流的,咱們怎麼控制它。

3.5. 導入activiti-explorer

1)      單元測試完成後,咱們能夠將該bpmn20.xml文件導入以前咱們部署的activiti-explorer應用中:點擊流程的流程設計工做區,點擊導入,將剛纔咱們編寫的文件導入進去。

2)      導入以後在右上角點擊部署。

3)      在已部署流程定義中咱們能夠看到這個流程,及它的流程圖。

4)      點擊啓動流程,該流程就會被啓動,再點擊任務中,列隊就會有該任務了,並且是分配給sales的,這正是咱們定義流程時所分配給的用戶組啊。注意,如今只有sales組的用戶才能夠看到此任務!

5)      sales組的用戶進入以後點擊「簽收」,該任務就分配給該用戶了,而後該用戶就能夠進行處理,也就是在代辦任務和受邀裏。

6)      進去以後點擊完成任務,該任務就流到下一個節點,也就是流轉到management組中去了,要由management組的用戶去處理。

7)      因而這時候,隊列中management組就有一個新的任務了,等待management組的成員來「簽收」,並完成任務。該流程也就結束了。

8)      此時就能夠查看歷史任務了,就是咱們這裏的「已歸檔」。用戶完成的任務會在這裏顯示。

這就是整個Demo的編寫、測試過程。這樣一個小小的流程基本可以體現出Activiti的功能及使用方法。

4. Eclipse中的Activiti插件

Activiti有一個Eclipse插件,Activiti Eclipse Designer,可用於圖形化建模、測試、部署 BPMN 2.0的流程。這樣就不用咱們本身去編寫繁瑣的流程文件了。具體安裝方法見手冊。

4.1. 安裝

打開 Help-> Install New Software.在以下面板中 , 點擊 Add 按鈕, 而後填入下列字段:

Name: Activiti BPMN 2.0 designer

Location: http://activiti.org/designer/update/

而後一步步的安裝就能夠了。

4.2. 使用

至於如何使用,文檔中介紹的很是詳細,這裏基於我初次使用的經驗,強調幾點:

1)      安裝以後將「保存bpmn文件時建立圖片文件」勾選上。這樣你每次保存bpmn文件時,會爲你自動建立圖片文件。

2)      節點的全部屬性可在properties控制檯中設置。

3)      在使用設計器以前,先去鑽研BPNM2.0規範吧,瞭解BPNM結構(可參看用戶手冊),才能畫出符合邏輯且完美的流程圖。

該例爲使用Activiti Eclipse Designer設計的「請假」流程圖。

http://blog.csdn.net/bluejoe2000/article/details/39530309

 

其餘關於Activiti學習的文章:

http://my.oschina.net/843294669/blog/719024

http://topmanopensource.iteye.com/blog/1315341

相關文章
相關標籤/搜索