国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Activiti初學(xué)者教程

2019-11-11 04:57:37
字體:
供稿:網(wǎng)友

1. 初識Activiti

1.1. 工作流與工作流引擎

工作流(workflow)就是工作流程的計算模型,即將工作流程中的工作如何前后組織在一起的邏輯和規(guī)則在計算機(jī)中以恰當(dāng)?shù)哪P瓦M(jìn)行表示并對其實施計算。它主要解決的是“使在多個參與者之間按照某種預(yù)定義的規(guī)則傳遞文檔、信息或任務(wù)的過程自動進(jìn)行,從而實現(xiàn)某個預(yù)期的業(yè)務(wù)目標(biāo),或者促使此目標(biāo)的實現(xiàn)”。(我的理解就是:將部分或者全部的工作流程、邏輯讓計算機(jī)幫你來處理,實現(xiàn)自動化)

所謂工作流引擎是指workflow作為應(yīng)用系統(tǒng)的一部分,并為之提供對各應(yīng)用系統(tǒng)有決定作用的根據(jù)角色、分工和條件的不同決定信息傳遞路由、內(nèi)容等級等核心解決方案。

例如開發(fā)一個系統(tǒng)最關(guān)鍵的部分不是系統(tǒng)的界面,也不是和數(shù)據(jù)庫之間的信息交換,而是如何根據(jù)業(yè)務(wù)邏輯開發(fā)出符合實際需要的程序邏輯并確保其穩(wěn)定性、易維護(hù)性和彈性。

比如你的系統(tǒng)中有一個任務(wù)流程,一般情況下這個任務(wù)的代碼邏輯、流程你都要自己來編寫。實現(xiàn)它是沒有問題的。但是誰能保證邏輯編寫的毫無紕漏?經(jīng)過無數(shù)次的測試與改進(jìn),這個流程沒有任何漏洞也是可以實現(xiàn)的,但是明顯就會拖慢整個項目的進(jìn)度。

 工作流引擎解決的就是這個問題:如果應(yīng)用程序缺乏強(qiáng)大的邏輯層,勢必變得容易出錯(信息的路由錯誤、死循環(huán)等等)。

1.2. BPMN2.0規(guī)范

BPMN(Business PRocess Model and Notation)--業(yè)務(wù)流程模型與符號。

BPMN是一套流程建模的標(biāo)準(zhǔn),主要目標(biāo)是被所有業(yè)務(wù)用戶容易理解的符號,支持從創(chuàng)建流程輪廓的業(yè)務(wù)分析到這些流程的最終實現(xiàn),知道最終用戶的管理監(jiān)控。

通俗一點其實就是一套規(guī)范,畫流程模型的規(guī)范。流程模型包括:流程圖、協(xié)作圖、編排圖、會話圖。詳細(xì)信息請google。

1.3. Activiti概述

1.3.1. Activiti由來

學(xué)習(xí)過Activiti的朋友都知道,Activiti的創(chuàng)始人也就是JBPM(也是一個優(yōu)秀的BPM引擎)的創(chuàng)始人,從Jboss離職后開發(fā)了一個新的BPM引擎:Activiti。所以,Activiti有很多地方都有JBPM的影子。所以,據(jù)說學(xué)習(xí)過JBPM的朋友學(xué)起Activiti來非常順手。

由于本人之前沒有工作流及JBPM的相關(guān)基礎(chǔ),剛開始學(xué)習(xí)Activiti的時候可以說是無比痛苦的,根本不知道從何下手,這里也建議大家先進(jìn)行工作流及BPMN2.0規(guī)范的學(xué)習(xí),有了一定的基礎(chǔ)后,再著手學(xué)習(xí)Activiti。

1.3.2. Activiti簡介

Activiti是一個開源的工作流引擎,它實現(xiàn)了BPMN 2.0規(guī)范,可以發(fā)布設(shè)計好的流程定義,并通過api進(jìn)行流程調(diào)度。

Activiti 作為一個遵從 Apache 許可的工作流和業(yè)務(wù)流程管理開源平臺,其核心是基于 java 的超快速、超穩(wěn)定的 BPMN2.0 流程引擎,強(qiáng)調(diào)流程服務(wù)的可嵌入性和可擴(kuò)展性,同時更加強(qiáng)調(diào)面向業(yè)務(wù)人員。

Activiti 流程引擎重點關(guān)注在系統(tǒng)開發(fā)的易用性和輕量性上。每一項 BPM 業(yè)務(wù)功能 Activiti 流程引擎都以服務(wù)的形式提供給開發(fā)人員。通過使用這些服務(wù),開發(fā)人員能夠構(gòu)建出功能豐富、輕便且高效的 BPM 應(yīng)用程序。

1.4. 文檔說明

以上部分對工作流、BPMN、Activiti的概念做了一個簡單的介紹,目的是了解Activiti究竟是什么,能做些什么…及在學(xué)習(xí)Activiti之前需要了解的知識與技術(shù)。其中大部分文字來自Copy網(wǎng)上的各種資料與文檔,通過總結(jié)而來的。具體的更詳細(xì)的內(nèi)容需自己google,參考一些官方的文檔與手冊。

本文檔之后內(nèi)容如下:

1)      下載與使用

2)      核心組件與說明

3)      入門示例

4)      Eclipse中的Activiti插件的使用

本文檔旨在為初學(xué)Activiti的朋友提供入門級別的參考,不會對其原理及其結(jié)構(gòu)進(jìn)行深層次的探究(更多是因為目前自身理解還不是很透徹),只是為大家理清思路,方便以后更深層次的學(xué)習(xí)。本文檔還有一個重要的特點,那就是根據(jù)自己看官方手冊的經(jīng)驗,教大家如何看手冊從而更有效率!由于是初學(xué),很多術(shù)語或解釋難免理解有偏差,所以一定要看官方提供的文檔與手冊,那才是學(xué)習(xí)的最佳途徑!

2. 開始學(xué)習(xí)

2.1. 必要的準(zhǔn)備

2.1.1. 下載與了解目錄

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

1)      database:里面存放的是Activiti使用到的數(shù)據(jù)庫信息的sql文件,它支持的數(shù)據(jù)庫類型如下圖,使用時只需執(zhí)行你自己的數(shù)據(jù)庫類型的文件即可。如:你的數(shù)據(jù)庫是MySQL,那么就執(zhí)行activiti.mysql.create.*.sql即可。

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

3)      libs:使用Activiti所需要的所有的jar包和源文件。

4)      wars:官方給我們提供的示例Demo,通過使用Demo可以更加快速的了解Activiti。

2.1.2. 其他準(zhǔn)備

使用Activiti,首先當(dāng)然要有jdk了!6+版本就可以了。其次,要有一款I(lǐng)DE,我們當(dāng)然會使用Eclipse,這里使用Juno版本。然后,web容器當(dāng)然也要有,這里使用Tomcat6.0版本。然后就是Activiti的Eclipse插件了,這個后面再介紹。

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

所謂的一分鐘入門就是通過運行你下載的包里的wars文件夾里的activiti-explorer.war文件,以便更快的了解Activiti。將文件拷貝至Tomcat的webapps目錄,啟動tomcat,輸入http://localhost:8080/activiti-explorer。然后你就可以開整了!總算是有一點微小的進(jìn)展了。

這里需要說明的就是,這個Demo默認(rèn)采用的是h2內(nèi)存數(shù)據(jù)庫,如果想用你自己的數(shù)據(jù)庫,就需要修改web應(yīng)用WEB-INF/classes目錄下的db.properties。然后,按上面說的,把database里的create文件夾里的數(shù)據(jù)庫文件導(dǎo)入你自己的數(shù)據(jù)庫(如果沒有修改db.properties,就不用導(dǎo)入了)。

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

對Demo的使用介紹在官方文檔的后面才開始介紹,這里建議應(yīng)用跑起來之后,先自己試試手(可看后面介紹Demo如何使用的章節(jié)),看看如何跑一個流程、整個流程是怎么流的、并隨時關(guān)注數(shù)據(jù)庫表里的數(shù)據(jù)的變化等,對以后的學(xué)習(xí)很有幫助!

2.2. 核心組件介紹

2.2.1. 關(guān)鍵對象

1.      Deployment:流程部署對象,部署一個流程時創(chuàng)建。

2.      ProcessDefinitions:流程定義,部署成功后自動創(chuàng)建。

3.      ProcessInstances:流程實例,啟動流程時創(chuàng)建。 

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

5.      Execution:執(zhí)行計劃,流程實例和流程執(zhí)行中的所有節(jié)點都是Execution,如UserTask、ServiceTask等。

2.2.2. 服務(wù)接口

1.      ProcessEngine:流程引擎的抽象,通過它我們可以獲得我們需要的一切服務(wù)。 

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

3.      RuntimeService:在Activiti中,每當(dāng)一個流程定義被啟動一次之后,都會生成一個相應(yīng)的流程對象實例。RuntimeService提供了啟動流程、查詢流程實例、設(shè)置獲取流程實例變量等功能。此外它還提供了對流程部署,流程定義和流程實例的存取服務(wù)。

4.      TaskService: 在Activiti中業(yè)務(wù)流程定義中的每一個執(zhí)行節(jié)點被稱為一個Task,對流程中的數(shù)據(jù)存取,狀態(tài)變更等操作均需要在Task中完成。TaskService提供了對用戶Task 和Form相關(guān)的操作。它提供了運行時任務(wù)查詢、領(lǐng)取、完成、刪除以及變量設(shè)置等功能。 

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

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

7.      HistoryService: HistoryService用于獲取正在運行或已經(jīng)完成的流程實例的信息,與RuntimeService中獲取的流程信息不同,歷史信息包含已經(jīng)持久化存儲的永久信息,并已經(jīng)被針對查詢優(yōu)化。

現(xiàn)在至少要知道有這些對象和接口。并結(jié)合Activiti Api這一章節(jié)來看,你就會對部署流程、啟動流程、執(zhí)行任務(wù)等操作有一個基本的概念。之后編寫一個簡單的單元測試,主要為了測試activiti.cfg.xml配置的是否正確,流程是否可以被部署即可。

至于與spring的集成,一定要熟悉基于Spring配置Activiti,以及事務(wù)的處理。

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

3.1. 概述

下面開始編寫一個示例。這個Demo為一個“月度報表申請”流程。由“sales(銷售)”組的用戶制作月度報表,提交給“management(經(jīng)理)”組的用戶,經(jīng)理審批該報表,最后結(jié)束。流程圖如下:

這個Demo完成之后,我們會進(jìn)行兩個測試。一個是代碼中的單元測試,就是跑一遍流程,看一下流程在跑的過程中輸出的信息;一個是我們將編輯好的bpmn20.xml文件通過我們之前一分鐘入門的示例activiti-explorer應(yīng)用導(dǎo)入進(jìn)去,查看它的流程圖,并完整執(zhí)行一遍流程。

在編寫這個Demo之前,至少要了解Activiti與Spring如何集成、XxxService各自的任務(wù)與作用,并完成上一章的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>

 

這里對部分代碼進(jìn)行解釋。

1)       文件的開頭部分,這里的id對于Activiti來說, 應(yīng)該叫做key。創(chuàng)建流程實例時,會根據(jù)此id來得到這個流程。

2)      開始流程。

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

sourceRef和targetRef分別為起始節(jié)點和目標(biāo)節(jié)點。

4)      描述用戶任務(wù)

id為該用戶任務(wù)的標(biāo)識。

documentation為該用戶任務(wù)的描述。

5)      分配用戶

可以把任務(wù)分配給指定的用戶,也可以分配給指定的組,并且可以有多個,詳見用戶手冊。

3.3. Spring配置文件

這里配置了數(shù)據(jù)源、事務(wù)管理、流程引擎及幾個必要的xxxService。這里數(shù)據(jù)源使用的是dbcp。數(shù)據(jù)庫信息就配置成你自己本地數(shù)據(jù)庫的信息,如果不會配置。

 

    <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應(yīng)用初始化時自動就會往數(shù)據(jù)庫里添加一些數(shù)據(jù),其中用戶組的表中就會添加幾條記錄,其中就包括這兩個組,所以不用管它怎么來的,總之?dāng)?shù)據(jù)庫里有這兩個組就對了。而應(yīng)用默認(rèn)使用的是內(nèi)存數(shù)據(jù)庫,服務(wù)一停止數(shù)據(jù)也就沒有了。所以為了進(jìn)行單元測試,需要按前面講的修改數(shù)據(jù)庫配置的方法:

把a(bǔ)ctiviti-explorer應(yīng)用的數(shù)據(jù)庫配置改成你自己的本地數(shù)據(jù)庫的信息,我使用的是Mysql數(shù)據(jù)庫。再啟動tomcat運行應(yīng)用(目的就是為了讓數(shù)據(jù)庫有數(shù)據(jù)),這時你的本地數(shù)據(jù)庫就有數(shù)據(jù)了,可以編寫測試用例進(jìn)行單元測試了。

3.4. 編寫測試用例

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

2)      編寫測試方法

   @Test

    public void monthtest() {

        // 部署流程定義

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

        // 啟動流程實例

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

        // 獲得第一個任務(wù)

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

        for (Task task : tasks) {

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

            // 認(rèn)領(lǐng)任務(wù)這里由foozie認(rèn)領(lǐng),因為fozzie是sales組的成員

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

        }

        // 查看fozzie現(xiàn)在是否能夠獲取到該任務(wù)

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

        for (Task task : tasks) {

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

            // 執(zhí)行(完成)任務(wù)

            taskService.complete(task.getId());

        }

        // 現(xiàn)在fozzie的可執(zhí)行任務(wù)數(shù)就為0了

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

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

        // 獲得第二個任務(wù)

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

        for (Task task : tasks) {

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

            // 認(rèn)領(lǐng)任務(wù)這里由kermit認(rèn)領(lǐng),因為kermit是management組的成員

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

        }

        // 完成第二個任務(wù)結(jié)束流程

        for (Task task : tasks) {

            taskService.complete(task.getId());

        }

        // 核實流程是否結(jié)束,輸出流程結(jié)束時間

        HistoricProcessInstancehistoricProcessInstance = historyService.createHistoricProcessInstanceQuery()

                                                                       .processInstanceId(procId).singleResult();

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

}

 

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

3.5. 導(dǎo)入activiti-explorer

1)      單元測試完成后,我們可以將該bpmn20.xml文件導(dǎo)入之前我們部署的activiti-explorer應(yīng)用中:點擊流程的流程設(shè)計工作區(qū),點擊導(dǎo)入,將剛才我們編寫的文件導(dǎo)入進(jìn)去。

2)      導(dǎo)入之后在右上角點擊部署。

3)      在已部署流程定義中我們可以看到這個流程,及它的流程圖。

4)      點擊啟動流程,該流程就會被啟動,再點擊任務(wù)中,列隊就會有該任務(wù)了,而且是分配給sales的,這正是我們定義流程時所分配給的用戶組啊。注意,現(xiàn)在只有sales組的用戶才可以看到此任務(wù)!

5)      sales組的用戶進(jìn)入之后點擊“簽收”,該任務(wù)就分配給該用戶了,然后該用戶就可以進(jìn)行處理,也就是在代辦任務(wù)和受邀里。

6)      進(jìn)去之后點擊完成任務(wù),該任務(wù)就流到下一個節(jié)點,也就是流轉(zhuǎn)到management組中去了,要由management組的用戶去處理。

7)      于是這時候,隊列中management組就有一個新的任務(wù)了,等待management組的成員來“簽收”,并完成任務(wù)。該流程也就結(jié)束了。

8)      此時就可以查看歷史任務(wù)了,就是我們這里的“已歸檔”。用戶完成的任務(wù)會在這里顯示。

這就是整個Demo的編寫、測試過程。這樣一個小小的流程基本能夠體現(xiàn)出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. 使用

至于如何使用,文檔中介紹的非常詳細(xì),這里基于我初次使用的經(jīng)驗,強(qiáng)調(diào)幾點:

1)      安裝之后將“保存bpmn文件時創(chuàng)建圖片文件”勾選上。這樣你每次保存bpmn文件時,會為你自動創(chuàng)建圖片文件。

2)      節(jié)點的所有屬性可在properties控制臺中設(shè)置。

3)      在使用設(shè)計器之前,先去鉆研BPNM2.0規(guī)范吧,了解BPNM結(jié)構(gòu)(可參看用戶手冊),才能畫出符合邏輯且完美的流程圖。

該例為使用Activiti Eclipse Designer設(shè)計的“請假”流程圖。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 扶风县| 崇信县| 石阡县| 阳城县| 龙口市| 化德县| 克东县| 化隆| 健康| 沁水县| 威远县| 清水河县| 汝南县| 洛川县| 淳安县| 禄丰县| 龙胜| 武冈市| 思茅市| 兰坪| 如东县| 扶余县| 云霄县| 连州市| 德化县| 左权县| 阿巴嘎旗| 德昌县| 鲜城| 远安县| 永安市| 津南区| 平潭县| 大丰市| 邵武市| 柳江县| 淄博市| 锡林郭勒盟| 亚东县| 五华县| 阳山县|