最簡單的Activiti入門教程

這篇文章主要講以下三個方面

  • 工作流介紹
  • 工作流執(zhí)行過程
  • 工作流模擬執(zhí)行

工作流介紹

以我們公司的報銷流程為例:
小明--->提交申請--->人事審批-->經(jīng)理審批-->財務(wù)審批--->結(jié)束
我們先思考一下,需要實(shí)現(xiàn)這的一個需求我們需要怎么做典鸡?
????我們可能需要去維護(hù)一個變量穴店,來不斷傳遞過去下一個處理者悲没,或者是建相關(guān)的任務(wù)表之類的晾咪,如果需求不會變祥楣,沒有什么條件處理检访,這樣也好設(shè)計眶拉。
????但是,如果有條件【不同職位員工審批方式不一樣】济欢,需求更改了【不需要人事審批了】赠堵,那么我們的代碼就會亂,不好維護(hù)法褥。
????再來看這種問題就是一種流式的控制管理茫叭,基于這么一個原因,我們需要學(xué)習(xí)一個框架來幫我們完成并管理這樣的報銷流程半等,他可以在上級點(diǎn)擊同意后自動將提交記錄錄到電腦并流轉(zhuǎn)到下一節(jié)點(diǎn)揍愁,這就是我們這里要講的工作流技術(shù)。

工作流(Workflow)杀饵,就是“業(yè)務(wù)過程的部分或整體在計算機(jī)應(yīng)用環(huán)境下的自動化”莽囤,它主要解決的是“使在多個參與者之間按照某種預(yù)定義的規(guī)則傳遞文檔、信息或任務(wù)的過程自動進(jìn)行切距,從而實(shí)現(xiàn)某個預(yù)期的業(yè)務(wù)目標(biāo)朽缎,或者促使此目標(biāo)的實(shí)現(xiàn)”

這里我們也可以比對出工作流的優(yōu)點(diǎn):
  1. 提高系統(tǒng)的柔性,適應(yīng)業(yè)務(wù)流程的變化
  2. 實(shí)現(xiàn)更好的業(yè)務(wù)過程控制谜悟,提高顧客服務(wù)質(zhì)量
  3. 降低系統(tǒng)開發(fā)和維護(hù)成本

工作流執(zhí)行過程

我們以官網(wǎng)提供的示例包演示:
官網(wǎng)https://www.activiti.org/get-started下載對應(yīng)的jar包饵沧,解壓出來,在wars包目錄下有個activiti-app.war赌躺,把這個包放到tomgcat運(yùn)行(運(yùn)行之前我把數(shù)據(jù)庫配置改成我本地的mysql:WEB-INF\classes\META-INF\activiti-app\activiti-app.properties

項(xiàng)目啟動成功進(jìn)入到首頁

1.png

  • Kickstart App:主要用于流程模型管理、表單管理及應(yīng)用(App)管理羡儿,一個應(yīng)用可以包含多個流程模型礼患,應(yīng)用可發(fā)布給其他用戶使用。
  • Task App:用于管理整個activiti-app的任務(wù),在該功能里面也可以啟動流程
  • Idenity management:身份信息管理缅叠,可以管理用戶悄泥、用戶組等數(shù)據(jù)

進(jìn)入第三個菜單Identity management
新建用戶:這邊新建用戶小明假設(shè)他為員工,王五是經(jīng)理

2.png

3.png

定義流程

在主界面點(diǎn)擊Kickstart App肤粱,點(diǎn)擊create Process按鈕彈出新建流程模型界面


4.png

5.png

6.png

上圖中定義了一個開始事件弹囚、兩個用戶任務(wù)、一個結(jié)束事件领曼。我們定義的請假業(yè)務(wù)鸥鹉,需要將該用戶任務(wù)分配給 小明。點(diǎn)擊第一個用戶任務(wù)庶骄,并修改“Assignment”屬性毁渗,將“提交申請”任務(wù)分配給“xiaoming”用戶。保存成功后单刁,再使用同樣的方法將“部門經(jīng)理審批”任務(wù)分配給 王五用戶灸异,保存流程模型后,就可以將流程發(fā)布羔飞。


7.png

發(fā)布流程

在 activiti-app 中肺樟,一個 App 可包含多個流程模型,因此在發(fā)布流程前逻淌,先新建一個 App并為其設(shè)置流程模型么伯。點(diǎn)擊 Apps 菜單,再點(diǎn)擊“Creaea App”按鈕恍风,新建一個 App蹦狂,該App就包含我們前面所設(shè)計的請假流程模型

8.png

建好之后需要為其設(shè)置流程模型
9.png

點(diǎn)擊一下即可,在關(guān)閉
q.png

點(diǎn)擊進(jìn)入到app中朋贬,點(diǎn)擊發(fā)布public進(jìn)行發(fā)布
w.png

發(fā)布成功后使用小明賬戶登錄凯楔,進(jìn)入到首頁可以看到
e.png

進(jìn)入請假流程模型App并且點(diǎn)擊“Processes”菜單,在界面左上角锦募,可以看到“Start a process”按鈕摆屯,點(diǎn)擊啟動請假流程后,可以看到界面如圖所示
r.png

點(diǎn)擊complete糠亩,完成虐骑,任務(wù)跳轉(zhuǎn)到下一個執(zhí)行人
t.png

直至整個流程審批完成,結(jié)束
y.png

工作流模擬執(zhí)行

在我們模擬工作流流程之前在介紹下工作流引擎

ProcessEngine對象赎线,這是Activiti工作的核心廷没。負(fù)責(zé)生成流程運(yùn)行時的各種實(shí)例及數(shù)據(jù)、監(jiān)控和管理流程的運(yùn)行垂寥,其主要有以下兩個職責(zé)

  • 定義流程颠黎,也就是給我們提供某種規(guī)范來定義規(guī)則另锋,以及如何定義一個流程的這種規(guī)范,同事我們可以根據(jù)工作流引擎提供的相關(guān)概念來定義更為復(fù)雜的流程狭归,這就是工作流引擎做的第一件事叫做定義流程夭坪。
  • 執(zhí)行流程,也就是工作流引擎需要解釋這個規(guī)則过椎,還要負(fù)責(zé)流程室梅,它相當(dāng)于流程的調(diào)度者,監(jiān)控每個流程的執(zhí)行情況疚宇,并將流程操作發(fā)往下一步亡鼠,或者根據(jù)條件休眠或終止流程的這么一個過程就叫做執(zhí)行流程。

????了解完工作流引擎的這兩個職責(zé)灰嫉,我相信對于什么是工作流引擎一定已經(jīng)有了一定的認(rèn)識了拆宛,我們在用一句稍微有點(diǎn)官方的話來總結(jié)一下工作流引擎:工作流引擎為我們提供相關(guān)規(guī)則概念的定義,給我們提供了相關(guān)的API來調(diào)用這個引擎去執(zhí)行流程讼撒。流程的操作實(shí)際上就是工作流引擎提供相關(guān)的api我們?nèi)フ{(diào)用它浑厚。

activiti.cfg.xml(activiti的配置文件)

Activiti核心配置文件,配置流程引擎創(chuàng)建工具的基本參數(shù)和數(shù)據(jù)庫連接池參數(shù)
定義數(shù)據(jù)庫配置參數(shù)

  • jdbcUrl: 數(shù)據(jù)庫的JDBC URL根盒。
  • jdbcDriver: 對應(yīng)不同數(shù)據(jù)庫類型的驅(qū)動钳幅。
  • jdbcUsername: 連接數(shù)據(jù)庫的用戶名。
  • jdbcPassword: 連接數(shù)據(jù)庫的密碼炎滞。

基于JDBC參數(shù)配置的數(shù)據(jù)庫連接 會使用默認(rèn)的MyBatis連接池敢艰。 下面的參數(shù)可以用來配置連接池(來自MyBatis參數(shù))

  • jdbcMaxActiveConnections: 連接池中處于被使用狀態(tài)的連接的最大值。默認(rèn)為10册赛。
  • jdbcMaxIdleConnections: 連接池中處于空閑狀態(tài)的連接的最大值钠导。
  • jdbcMaxCheckoutTime: 連接被取出使用的最長時間,超過時間會被強(qiáng)制回收森瘪。 默認(rèn)為20000(20秒)牡属。
  • jdbcMaxWaitTime: 這是一個底層配置,讓連接池可以在長時間無法獲得連接時扼睬, 打印一條日志逮栅,并重新嘗試獲取一個連接。(避免因?yàn)殄e誤配置導(dǎo)致沉默的操作失敶坝睢)措伐。 默認(rèn)為20000(20秒)

下面所有的操作都需要用到工作流引擎對象,我們可以如下方式獲染 :

    ProcessEngine processEngine= ProcessEngines.getDefaultProcessEngine();

這里默認(rèn)會去資源路徑下讀取配置文件activiti.cfg.xml

我們再來回顧下工作流執(zhí)行過程侥加,首先需要畫好流程圖,然后部署到app上
這個步驟我們叫:部署流程定義

 public void deploymentProcessDefinition(){
        Deployment deploy = processEngine.getRepositoryService()  //與流程定義和部署對象相關(guān)的Service
                .createDeployment()  //創(chuàng)建一個部署對象
                .name("審批流程")     //添加部署名稱
                .addClasspathResource("diagrams/audit.xml")  //從classPath資源中加載粪躬,一次只能加載一個文件
                .addClasspathResource("diagrams/audit.png")
                .deploy();  //完成部署
    }

說明:

  • 首先獲得默認(rèn)的流程引擎担败,通過流程引擎獲取了一個RepositoryService對象(倉庫對象)
  • 由倉庫的服務(wù)對象產(chǎn)生一個部署對象配置對象矗蕊,用來封裝部署操作的相關(guān)配置。
  • 這是一個鏈?zhǔn)骄幊糖饧埽诓渴鹋渲脤ο笾性O(shè)置顯示名,上傳流程定義規(guī)則文件
  • 向數(shù)據(jù)庫表中存放流程定義的規(guī)則信息朋魔。
這一步在數(shù)據(jù)庫中將操作三張表
  • act_re_deployment(部署對象表)
    存放流程定義的顯示名和部署時間岖研,每部署一次增加一條記錄
  • act_re_procdef(流程定義表)
    存放流程定義的屬性信息,部署每個新的流程定義都會在這張表中增加一條記錄警检。
    注意:當(dāng)流程定義的key相同的情況下孙援,使用的是版本升級
  • act_ge_bytearray(資源文件表)
    存儲流程定義相關(guān)的部署信息。即流程定義文檔的存放地扇雕。每部署一次就會增加兩條記錄拓售,一條是關(guān)于bpmn規(guī)則文件的,一條是圖片的(如果部署時只指定了bpmn一個文件镶奉,activiti會在部署時解析bpmn文件內(nèi)容自動生成流程圖)础淤。兩個文件不是很大,都是以二進(jìn)制形式存儲在數(shù)據(jù)庫中
然后需要發(fā)布:啟動流程
    public void startProcess(){
        ProcessInstance process = processEngine.getRuntimeService().startProcessInstanceByKey("myProcess_1");
    }

操作數(shù)據(jù)庫的act_ru_execution表,如果是用戶任務(wù)節(jié)點(diǎn)哨苛,同時也會在act_ru_task添加一條記錄鸽凶,我們可以看到小明會有一條任務(wù),查詢操作如下:

        List<Task> taskList = processEngine.getTaskService()//與正在執(zhí)行的任務(wù)管理相關(guān)的Service
                .createTaskQuery()//創(chuàng)建任務(wù)查詢對象
                /**查詢條件(where部分)*/
                .taskAssignee("小明")//指定個人任務(wù)查詢建峭,指定辦理人
//                      .taskCandidateUser(candidateUser)//組任務(wù)的辦理人查詢
//                      .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
//                      .processInstanceId(processInstanceId)//使用流程實(shí)例ID查詢
//                      .executionId(executionId)//使用執(zhí)行對象ID查詢
                /**排序*/
                .orderByTaskCreateTime().asc()//使用創(chuàng)建時間的升序排列
                /**返回結(jié)果集*/
//                      .singleResult()//返回惟一結(jié)果集
//                      .count()//返回結(jié)果集的數(shù)量
//                      .listPage(firstResult, maxResults);//分頁查詢
                .list();//返回列表
        for (Task task:taskList){
            System.out.println("任務(wù)ID:"+task.getId());
            System.out.println("任務(wù)名稱:"+task.getName());
            System.out.println("任務(wù)的創(chuàng)建時間:"+task.getCreateTime());
            System.out.println("任務(wù)的辦理人:"+task.getAssignee());
            System.out.println("流程實(shí)例ID:"+task.getProcessInstanceId());
            System.out.println("執(zhí)行對象ID:"+task.getExecutionId());
            System.out.println("流程定義ID:"+task.getProcessDefinitionId());
        }

說明

  • 因?yàn)槭侨蝿?wù)查詢玻侥,所以從processEngine中應(yīng)該得到TaskService
  • 使用TaskService獲取到任務(wù)查詢對象TaskQuery
  • 為查詢對象添加查詢過濾條件,使用taskAssignee指定任務(wù)的辦理者(即查詢指定用戶的代辦任務(wù))亿蒸,同時可以添加分頁排序等過濾條件
  • 調(diào)用list方法執(zhí)行查詢凑兰,返回辦理者為指定用戶的任務(wù)列表
  • 任務(wù)ID、名稱边锁、辦理人姑食、創(chuàng)建時間可以從act_ru_task表中查到。
  • 一個Task節(jié)點(diǎn)和Execution節(jié)點(diǎn)是1對1的情況砚蓬,在task對象中使用Execution_來表示他們之間的關(guān)系
  • 任務(wù)ID在數(shù)據(jù)庫表act_ru_task中對應(yīng)“ID_”列
完成任務(wù)
    public void completeMyPersonalTask(){
        processEngine.getTaskService().  //正在執(zhí)行任務(wù)相關(guān)的Service
                complete("104");  //根據(jù)taskid完成任務(wù)
    }

說明

  • 是辦理任務(wù)矢门,所以從ProcessEngine得到的是TaskService。
  • 當(dāng)執(zhí)行完這段代碼灰蛙,再以員工的身份去執(zhí)行查詢的時候祟剔,會發(fā)現(xiàn)這個時候已經(jīng)沒有數(shù)據(jù)了,因?yàn)檎趫?zhí)行的任務(wù)中沒有數(shù)據(jù)摩梧。
  • 對于執(zhí)行完的任務(wù)物延,activiti將從act_ru_task表中刪除該任務(wù),下一個任務(wù)會被插入進(jìn)來仅父。
  • 以”部門經(jīng)理”的身份進(jìn)行查詢叛薯,可以查到結(jié)果浑吟。因?yàn)榱鞒虉?zhí)行到部門經(jīng)理審批這個節(jié)點(diǎn)了。
  • 再執(zhí)行辦理任務(wù)代碼耗溜,執(zhí)行完以后以”部門經(jīng)理”身份進(jìn)行查詢组力,沒有結(jié)果。
  • 重復(fù)第4和5步直到流程執(zhí)行完抖拴。
綜上燎字,我們可以總結(jié)出這個幾個Service
  • RepositoryService
    是Activiti的倉庫服務(wù)類。所謂的倉庫指流程定義文檔的兩個文件:bpmn文件和流程圖片阿宅。
  • RuntimeService
    是activiti的流程執(zhí)行服務(wù)類候衍。可以從這個服務(wù)類中獲取很多關(guān)于流程執(zhí)行相關(guān)的信息洒放。
  • TaskService
    是activiti的任務(wù)服務(wù)類蛉鹿。可以從這個類中獲取任務(wù)的信息往湿。
  • HistoryService
    是activiti的查詢歷史信息的類妖异。在一個流程執(zhí)行完成后,這個對象為我們提供查詢歷史信息煌茴。
亦可以總結(jié)所用到的表
  • ACT_RE_*: 'RE'表示repository随闺。 這個前綴的表包含了流程定義和流程靜態(tài)資源 (圖片,規(guī)則蔓腐,等等)矩乐。
  • ACT_RU_*: 'RU'表示runtime。 這些運(yùn)行時的表回论,包含流程實(shí)例散罕,任務(wù),變量傀蓉,異步任務(wù)欧漱,等運(yùn)行中的數(shù)據(jù)。 Activiti只在流程實(shí)例執(zhí)行過程中保存這些數(shù)據(jù)葬燎, 在流程結(jié)束時就會刪除這些記錄误甚。 這樣運(yùn)行時表可以一直很小速度很快。
  • ACT_ID_*: 'ID'表示identity谱净。 這些表包含身份信息窑邦,比如用戶,組等等壕探。
  • ACT_HI_*: 'HI'表示history冈钦。 這些表包含歷史數(shù)據(jù),比如歷史流程實(shí)例李请, 變量瞧筛,任務(wù)等等厉熟。
  • ACT_GE_*: 通用數(shù)據(jù), 用于不同場景下较幌,如存放資源文件揍瑟。

資源庫流程規(guī)則表

  1. act_re_deployment 部署信息表
  2. act_re_model 流程設(shè)計模型部署表
  3. act_re_procdef 流程定義數(shù)據(jù)表
    運(yùn)行時數(shù)據(jù)庫表
  4. act_ru_execution 運(yùn)行時流程執(zhí)行實(shí)例表
  5. act_ru_identitylink 運(yùn)行時流程人員表,主要存儲任務(wù)節(jié)點(diǎn)與參與者的相關(guān)信息
  6. act_ru_task 運(yùn)行時任務(wù)節(jié)點(diǎn)表
  7. act_ru_variable 運(yùn)行時流程變量數(shù)據(jù)表
  8. act_ru_job 工作數(shù)據(jù)表
  9. act_ru_event_subscr 事件描述表
    歷史數(shù)據(jù)庫表
  10. act_hi_actinst 歷史節(jié)點(diǎn)表
  11. act_hi_attachment 歷史附件表
  12. act_hi_comment 歷史意見表
  13. act_hi_identitylink 歷史流程人員表
  14. act_hi_detail 歷史詳情表乍炉,提供歷史變量的查詢
  15. act_hi_procinst 歷史流程實(shí)例表
  16. act_hi_taskinst 歷史任務(wù)實(shí)例表
  17. act_hi_varinst 歷史變量表
    組織機(jī)構(gòu)表
  18. act_id_group 用戶組信息表
  19. act_id_info 用戶擴(kuò)展信息表
  20. act_id_membership 用戶與用戶組對應(yīng)信息表
  21. act_id_user 用戶信息表
    通用數(shù)據(jù)表
  22. act_ge_bytearray 二進(jìn)制數(shù)據(jù)表
  23. act_ge_property 屬性數(shù)據(jù)表存儲整個流程引擎級別的數(shù)據(jù),初始化表結(jié)構(gòu)時月培,會默認(rèn)插入三條記錄,


    27102725_uKzQ.jpg

企業(yè)中的應(yīng)用

未完

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恩急,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纪蜒,更是在濱河造成了極大的恐慌衷恭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纯续,死亡現(xiàn)場離奇詭異随珠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)猬错,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門窗看,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人倦炒,你說我怎么就攤上這事显沈。” “怎么了逢唤?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵拉讯,是天一觀的道長。 經(jīng)常有香客問我鳖藕,道長魔慷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任著恩,我火速辦了婚禮院尔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喉誊。我一直安慰自己邀摆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布裹驰。 她就那樣靜靜地躺著隧熙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪幻林。 梳的紋絲不亂的頭發(fā)上贞盯,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天音念,我揣著相機(jī)與錄音,去河邊找鬼躏敢。 笑死闷愤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的件余。 我是一名探鬼主播讥脐,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼啼器!你這毒婦竟也來了旬渠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤端壳,失蹤者是張志新(化名)和其女友劉穎告丢,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體损谦,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岖免,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了照捡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颅湘。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖栗精,靈堂內(nèi)的尸體忽然破棺而出闯参,到底是詐尸還是另有隱情,我是刑警寧澤悲立,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布赢赊,位于F島的核電站,受9級特大地震影響级历,放射性物質(zhì)發(fā)生泄漏释移。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一寥殖、第九天 我趴在偏房一處隱蔽的房頂上張望玩讳。 院中可真熱鬧,春花似錦嚼贡、人聲如沸熏纯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽樟澜。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秩贰,已是汗流浹背霹俺。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工窑滞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拍屑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓辣之,卻偏偏與公主長得像觅玻,于是被迫代替她去往敵國和親想际。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容