Activiti快速入門(三)—— 部署啟動審批流程

1. 部署流程

部署流程的2大前提:

  • 流程引擎
  • 流程定義文件
    流程引擎就不再多說了镀脂,無論是前面的哪種方式獲取的矩肩,在部署上是一致的铡原。
    本篇的相關(guān)源碼:GitHub

流程定義文件需要通過IDEA的纱新、eclipse 中的 Activiti designer插件或者Web 編輯器Activiti modeler來的設(shè)計篮奄,且得到一個以.bpmn為后綴的流程定義文件
安裝完成插件后在Eclipse 右鍵new—Other—Activiti Diagram即可新建流程定義文件
Activiti designer插件設(shè)計界面如下

eclipse activiti modeler.PNG

IDEA 安裝完成插件后在任意目錄下右鍵new BpmnFile 即可新建流程定義文件
actibpm 插件設(shè)計界面如下

IDEA actiBPM.PNG

這里如果遇到actiBPM插件中文亂碼則需要在IDEA安裝目錄下找到idea.exe.vmoptions和idea64.exe.vmoptions這兩個文件捆愁,且在最后一行添加如下配置

-Dfile.encoding=UTF-8

設(shè)計器中有很多元素可以供我們選擇割去,但是在入門階段,我認為只需要關(guān)注StartEvent UserTask EndEvent 這3個元素即可昼丑,簡單場景下呻逆,也只會用到這3個。

設(shè)計器元素

在我們定義好了流程定義文件后菩帝,就可以使用流程引擎部署它了咖城,前提是你已經(jīng)搭建好了Activiti的項目環(huán)境,這里可以參考快速入門(二)

@Test
    public void deployMyProcess() throws FileNotFoundException {
        //幾乎所有需要操作到流程文件胁附,或者讀取流程相關(guān)信息的酒繁,都是使用倉庫服務repositoryService
        //部署流程 這里跟構(gòu)建流程引擎的方式差不多,都是使用了構(gòu)建者模式
        //1. 首先創(chuàng)建DeploymentBuilder對象,通過這個對象控妻,我們可以指定要加載的流程定義文件州袒,以及一些其他屬性。
        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
        //2.1 加載流程文件弓候,從類路徑加載
//        deploymentBuilder.addClasspathResource("AskForLeave.bpmn");
        //2.使用InputStream加載 (替換自己的文件路徑)
        FileInputStream fileInputStream = new FileInputStream("E:\\DemoProjects\\ActivitiExample\\ActivitiFirstDeploy\\src\\main\\resources\\AskForLeave.bpmn");
        deploymentBuilder.addInputStream("AskForLeave.bpmn", fileInputStream);
        deploymentBuilder.name("測試部署請假流程");
        //還有將多個bpmn文件打包批量郎哭,以及字符串這兩種部署方式(這里暫時不介紹這兩種方式)
        //執(zhí)行部署,直到調(diào)用deploy()方法才是真正的部署到引擎中了
        //同時會在act_ge_bytearray ,act_re_deployment ,act_re_procdef這3個表中插入相關(guān)信息
        //與以前的教程不一樣的是菇存,別的教程中會經(jīng)常將流程圖片和流程bpmn文件一起部署夸研,但我認為有點多余了,因為在部署bpmn的時候會自動生成流程圖片
        Deployment deploy = deploymentBuilder.deploy();
        //這個是創(chuàng)建一個部署查詢對象查詢依鸥,查詢的是act_re_deployment表這個表記錄的就是deploymentBuilder對象所附加的屬性
        long count = repositoryService.createDeploymentQuery().count();
        System.out.println("部署時間:"+deploy.getDeploymentTime());
        Assert.assertEquals(1, count);
    }

在流程部署完成后亥至,我們來看一看數(shù)據(jù)庫的變化,學習Activiti引擎就必須要對這20多張表有一個比較深刻的了解贱迟。
部署一個流程姐扮,數(shù)據(jù)庫中有act_ge_bytearray ,act_re_deployment ,act_re_procdef這3個表會發(fā)生變化

  • act_re_deployment 中插入了deploymentBuilder構(gòu)建時所附帶的信息,比如name衣吠,key茶敏,category等但是這幾個信息都是非必填項,目前即便是為空也不影響缚俏,主要是為了定義和區(qū)分不同的部署信息惊搏。


    act_re_deployment
  • act_re_procdef 這個表中插入的是比較重要的信息了,這里面的Name忧换,Key恬惯,Category 等等都是流程引擎從我們自己設(shè)計的AskForLeave.bpmn這個流程定義文件中解析出來的屬性,在實際業(yè)務中最常關(guān)聯(lián)的也就是這個表中的屬性亚茬。


    act_re_procdef
  • act_ge_bytearray在第一節(jié)中有提到過ge系列的是通用數(shù)據(jù)宿崭,可以看成是系統(tǒng)將我們的bpmn文件以及它解析這個文件生成的流程圖片以二進制的形式保存到這個表中了


    act_ge_bytearray

當流程部署完成后,我們就可以調(diào)用Api啟動這個請假流程

2. 啟動流程

啟動流程的方法有很多重載最主要的就是下面展示的兩種方式

    @Test
    public void startAskLeaveProcess() {
        //1.通過流程定義ID啟動才写,這個ID就是act_re_procdef的主鍵ID 例如Leave:1:4
        //runtimeService.startProcessInstanceById();
        //2.通過流程定義的Key啟動葡兑,這個Key是在我們畫流程圖的時候輸入的ID
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(LEAVEKEY);
        Assert.assertEquals(LEAVEKEY, processInstance.getProcessDefinitionKey());
        System.out.println("啟動時間:"+processInstance.getStartTime());
    }

啟動流程成功后奖蔓,我們來看看數(shù)據(jù)庫之中的變化

  • act_ru_task RU當前任務表 是Runtime的縮寫
    證明這個表中存放的是當前系統(tǒng)中的任務(也就是設(shè)計流程時的Task類型的節(jié)點)其中最重要的屬性有如下:

ID:當前任務的ID(可以使用TaskService查詢)
EXECUTION_ID_: 執(zhí)行ID
PROC_INST_ID_: 流程實例ID 這個屬性非常重要,它貫穿了流程實例的整個生命周期讹堤,從啟動到結(jié)束到歷史記錄查詢都非常依賴于它吆鹤,它是流程實例的唯一標識
Name: 當前任務節(jié)點的名稱(自己定義的)
TASK_DEF_KEY_: 任務定義Key 用戶定義的任務Key

act_ru_task當前任務表
  • act_ru_execution 當前執(zhí)行表
    這個表可以看做是比Task記錄的節(jié)點更詳細的表,因為act_ru_task僅僅會保存Task屬性的節(jié)點洲守,而這個表會記錄所有的節(jié)點疑务,而且它主要用于子流程,或者并行流程復雜用法的時候才需要特別關(guān)心梗醇,現(xiàn)在暫時不用詳細了解
act_ru_execution 當前執(zhí)行表

除了RU系列運行時查詢的表知允,還會有對應的歷史記錄保存表

  • act_hi_taskinst 歷史任務流程實例表 保存的內(nèi)容大體跟ru_task一致


    歷史任務表
  • act_hi_procinst歷史流程實例表
    這個表存儲的信息也比較重要,主要用于查詢流程的詳細信息叙谨,比如啟動時間温鸽,啟動人結(jié)束時間等等


    流程實例表
  • act_hi_actinst流程活動實例表 這個表從存儲的內(nèi)容來說和act_ru_execution比較像,它會把流程所有已經(jīng)流轉(zhuǎn)過的節(jié)點都記錄下來


    流程活動實例表

    從上述數(shù)據(jù)庫變化中大家應該可以初步熟悉流程表的核心了手负,啟動任何一個流程上面的5張表都會產(chǎn)生新記錄涤垫,也可以說Activiti的核心功能是重度依賴這5張表的

Activiti中有不少的Query查詢對象,他們是通過各個Service獲取的竟终,目的也主要是查詢數(shù)據(jù)庫表蝠猬,我們就以上面的act_hi_procinst為例

    @Test
    public void listAllProcess(){
        //創(chuàng)建Query查詢對象 可以在這個對象后面調(diào)用各種方法實現(xiàn)條件查詢,排序等
        HistoricProcessInstanceQuery hisProcInstanceQuery = historyService.createHistoricProcessInstanceQuery();
        //不加查詢條件
        List<HistoricProcessInstance> processInstances = hisProcInstanceQuery.list();
        for (HistoricProcessInstance processInstance : processInstances) {
            System.out.println(processInstance.getId());
            System.out.println(processInstance.getDeploymentId());
            System.out.println(processInstance.getProcessDefinitionName());
        }
        //根據(jù)流程定義名稱查詢
        List<HistoricProcessInstance> processInstances1 = hisProcInstanceQuery.processDefinitionName("我的流程").list();
        //根據(jù)流程實例ID查詢
        HistoricProcessInstance processInstance = hisProcInstanceQuery.processInstanceId("2501").singleResult();
        //查詢未結(jié)束的流程
        List<HistoricProcessInstance> processInstances2 = hisProcInstanceQuery.unfinished().list();
        Assert.assertEquals(1, processInstances1.size());
        Assert.assertNotNull(processInstance);
        Assert.assertEquals(1, processInstances2.size());
    }

辦理任務

流程啟動之后肯定是需要辦理任務的统捶,act_ru_task中的每一行就是我們需要處理的任務榆芦,首先熟悉一下如何查詢他們,同上依然先創(chuàng)建Query對象

    @Test
    public void getTask() {
        //如果你的數(shù)據(jù)庫中只有一條流程那么也是可以將list()改為singleResult()的
        List<HistoricProcessInstance> processInstances = historyService
                .createHistoricProcessInstanceQuery().unfinished().list();
        List<Task> tasks = new ArrayList<>();
        for (HistoricProcessInstance processInstance : processInstances) {
            String processInstanceId = processInstance.getId();
            Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
            tasks.add(task);
        }
        tasks.forEach(task -> System.out.println(task.getName()));

        for (Task task : tasks) {
            //TaskService可以完成某個任務的審批喘鸟,使流程流轉(zhuǎn)到下一節(jié)點歧杏,比如用戶申請審批完成后到達領(lǐng)導審批節(jié)點
            taskService.complete(task.getId());
            Task result = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            System.out.println(result.getName());
        }
    }

控制臺輸出如下

用戶申請
領(lǐng)導審批

再看數(shù)據(jù)庫之前的那一行ID為2505的用戶申請已經(jīng)沒有了,新增了5002的領(lǐng)導審批記錄迷守,這些都是流程引擎自動為我們完成的


當前任務

我們在歷史活動和歷史任務中都會插入一條新記錄(新的節(jié)點或者任務),且更新之前辦理的任務的END_TIME用來表示他們的處理時間


歷史活動實例表
歷史任務實例表

在我們最終調(diào)用TaskService.complete()完成最后一個任務的審批后旺入,會更新歷史流程實例的完成時間兑凿,這就代表這個流程已經(jīng)結(jié)束了所有的ru跟他相關(guān)的都會被清空


歷史流程實例
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市茵瘾,隨后出現(xiàn)的幾起案子礼华,更是在濱河造成了極大的恐慌,老刑警劉巖拗秘,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圣絮,死亡現(xiàn)場離奇詭異,居然都是意外死亡雕旨,警方通過查閱死者的電腦和手機扮匠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門捧请,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棒搜,你說我怎么就攤上這事疹蛉。” “怎么了力麸?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵可款,是天一觀的道長。 經(jīng)常有香客問我克蚂,道長闺鲸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任埃叭,我火速辦了婚禮摸恍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘游盲。我一直安慰自己误墓,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布益缎。 她就那樣靜靜地躺著谜慌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪莺奔。 梳的紋絲不亂的頭發(fā)上欣范,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音令哟,去河邊找鬼恼琼。 笑死,一個胖子當著我的面吹牛屏富,可吹牛的內(nèi)容都是我干的晴竞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼狠半,長吁一口氣:“原來是場噩夢啊……” “哼噩死!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起神年,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤已维,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后已日,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垛耳,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了堂鲜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栈雳。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泡嘴,靈堂內(nèi)的尸體忽然破棺而出甫恩,到底是詐尸還是另有隱情,我是刑警寧澤酌予,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布磺箕,位于F島的核電站,受9級特大地震影響抛虫,放射性物質(zhì)發(fā)生泄漏松靡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一建椰、第九天 我趴在偏房一處隱蔽的房頂上張望雕欺。 院中可真熱鬧,春花似錦棉姐、人聲如沸屠列。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笛洛。三九已至,卻和暖如春乃坤,著一層夾襖步出監(jiān)牢的瞬間苛让,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工湿诊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狱杰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓厅须,卻偏偏與公主長得像仿畸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子朗和,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

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