溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Activiti的知識(shí)點(diǎn)分析是什么

發(fā)布時(shí)間:2021-10-21 09:16:50 來源:億速云 閱讀:141 作者:柒染 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)Activiti的知識(shí)點(diǎn)分析是什么,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1.查詢接口createXxxQuery

查詢接口中的Xxx即為各種對(duì)象的查詢方式,如createProcessDefinitionQuery為查詢流程定義的方法。查詢最后的調(diào)用有如下通用方法:

  • asc:升序,和list配合使用

  • desc:倒序,和list配合使用

  • count:返回計(jì)數(shù)

  • list:返回一個(gè)list

  • listPage:返回分頁list

  • singleResult:返回單個(gè)對(duì)象

不同的查詢接口需要調(diào)用不同的服務(wù)組件,如repositoryService提供流程定義相關(guān)的查詢;identityService服務(wù)組件提供用戶、用戶組相關(guān)的查詢;runtimeService提供流程實(shí)例相關(guān)的查詢。

①常規(guī)查詢:如下查詢?yōu)槁暶髁艘粋€(gè)流程定義processDefinition來接受查詢返回的單個(gè)對(duì)象,流程定義需要調(diào)用repositoryService服務(wù)組件中的createProcessDefinition,根據(jù)部署的id獲取,流程定義的單個(gè)實(shí)體。

ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery().
                deploymentId(deployment.getId()).singleResult();

②自定義sql查詢:可以使用自定義sql去根據(jù)數(shù)據(jù)庫字段查詢數(shù)據(jù):

List<Group> groups=identityService.createNativeGroupQuery().sql("SELECT * FROM ACT_ID_GROUP where NAME=#{name}").parameter("name","group2");

2.流程文件部署

流程定義部署使用DeploymenBuilder對(duì)象,該對(duì)象提供了以下方法來實(shí)現(xiàn)流程部署:

  • addClasspathResource

  • addInputStream

  • addString

  • addZipInputStream

  • addBpmnModel

  • addBytes

  • deploy

如我們正常部署一個(gè)bpmn文件定義的流程定義使用如下代碼:

DeploymentBuilder builder=repositoryService.createDeployment();
builder.addClasspathResource("test1.bpmn");
builder.deploy();

先使用DeploymenBuilder類來生命了一個(gè)builder對(duì)象,并通過repositoryService來創(chuàng)建部署,在之后使用builder的addClasspathResource方法將bpmn部署到數(shù)據(jù)庫中,在此過程中該方法不僅回將bpmn文件內(nèi)容存入數(shù)據(jù)庫,也會(huì)根據(jù)bpmn生成對(duì)應(yīng)的流程圖png文件以通存入數(shù)據(jù)庫。

流程定義部署完成后,還可以終止或激活流程定義,當(dāng)終止流程定義時(shí),該流程定義的流程實(shí)例不能再被啟動(dòng)。

//終止流程定義
repositoryService.suspendProcessDefinitionByKey(ProcessDefinitionKey);
//啟動(dòng)流程定義
repositoryService.activateProcessDefinitionByKey(ProcessDefinitionKey);

3.任務(wù)操作

任務(wù)候選人(組):表示該任務(wù)可以由某個(gè)用戶組(如經(jīng)理)來完成。

任務(wù)持有人(owner):完成該任務(wù)時(shí)某個(gè)人的職責(zé),那么這個(gè)人是此任務(wù)的持有人,一個(gè)任務(wù)只能由一個(gè)持有人。

任務(wù)代理人(assignee):由于本人不能及時(shí)處理任務(wù),而委托給他人,這個(gè)人就是此任務(wù)代理人,一個(gè)任務(wù)只能由一個(gè)代理人。

對(duì)任務(wù)設(shè)置候選人,使用addCandidateUser將用戶設(shè)置為某個(gè)人物的候選人,并將這種綁定關(guān)系記錄到ACT_RU_IDENTITYLINK表中,代碼如下:

String taskId = UUID.randomUUID().toString();
//此處因?yàn)橹皇莇emo所以直接創(chuàng)建了一個(gè)task,正常情況下應(yīng)該從流程實(shí)例中取出task
Task task = ts.newTask(taskId);
task.setName("測(cè)試任務(wù)");
ts.saveTask(task);
//  創(chuàng)建用戶
String userId = UUID.randomUUID().toString();
User user = is.newUser(userId);
user.setFirstName("angus");
is.saveUser(user);
// 設(shè)置任務(wù)的候選用戶
ts.addCandidateUser(taskId, userId);

//設(shè)置任務(wù)的持有用戶
ts.setOwner(taskId, userId);

//設(shè)置任務(wù)的代理人,只能被聲明一次代理人,再次聲明會(huì)報(bào)錯(cuò)
ts.claim(taskId, userId);

4.任務(wù)參數(shù)與附件

如何給任務(wù)設(shè)置參數(shù):

//簡(jiǎn)單的任務(wù)參數(shù)保存在ACT_RU_VARIABLE表中
taskSevice.setVariable(task.id,"var1","hello");

//任務(wù)參數(shù)也可以保存一個(gè)對(duì)象,但是保存的對(duì)應(yīng)類必須已經(jīng)實(shí)現(xiàn)了serialize可序列話接口
//如果保存對(duì)象,數(shù)據(jù)即序列話后的對(duì)象將會(huì)額外保存到ACT_GE_BYTEARRAY
taskSevice.setVariable(task.id,"person1",p);
//取出存入的對(duì)象
Person p=taskSevice.getVariable(task.id,"person1",Person.class);

任務(wù)參數(shù)有著不同的作用域:

  • 本地參數(shù)(setVariableLocal):當(dāng)前節(jié)點(diǎn)完成后,參數(shù)就會(huì)失效。

  • 全局參數(shù)(setVariable):一直有效。

除了使用java代碼set參數(shù)外,還可以在流程xml文件中保存參數(shù):

        <dataObject id="personName" name="personName"
            itemSubjectRef="xsd:string">
            <extensionElements>
                <activiti:value>Crazyit</activiti:value>
            </extensionElements>
        </dataObject>

獲取方法如下:

        String var = taskService.getVariable(task.getId(), "personName", String.class);

5.啟動(dòng)流程實(shí)例

流程實(shí)例(ProcessInstance)可以理解為我們根據(jù)流程定義(類)而創(chuàng)建的“對(duì)象”。

執(zhí)行流(Execution)簡(jiǎn)單理解為工作流圖中的一條條線路,而流程實(shí)例繼承了執(zhí)行流,因此也被稱為著執(zhí)行流。

ProcessInstance可以直接使用runService的startProcessInstance方法開創(chuàng)建,創(chuàng)建成功后他的數(shù)據(jù)將會(huì)被保存在ACT_RU_EXECUTION表中,需要注意的是盡管流程圖如圖只有一根線路,數(shù)據(jù)庫中也會(huì)出現(xiàn)兩條數(shù)據(jù),一條為主執(zhí)行流,一條為子執(zhí)行流。

Activiti的知識(shí)點(diǎn)分析是什么

無論工作流圖是怎么樣的,都必定有一個(gè)主執(zhí)行流,而有多少個(gè)分支就會(huì)有多少個(gè)子執(zhí)行流。

startProcessInstance主要有三類分別是根據(jù)id、key和message消息來啟動(dòng),前兩個(gè)就是根據(jù)流程定義的id、key來啟動(dòng),最后一個(gè)消息是等待一個(gè)消息來創(chuàng)建流程實(shí)例。

6.流程實(shí)例的運(yùn)行

一般流程前進(jìn)使用trigger方法,使用流程的id傳參

        Execution exe = runService.createExecutionQuery()
                .processInstanceId(pi.getId()).onlyChildExecutions()
                .singleResult();

        System.out.println(pi.getId() + ", 當(dāng)前節(jié)點(diǎn):" + exe.getActivityId());
        
        // 讓它往前走
        runService.trigger(exe.getId());
        
        exe = runService.createExecutionQuery()
                .processInstanceId(pi.getId()).onlyChildExecutions()
                .singleResult();
        System.out.println(pi.getId() + ", 當(dāng)前節(jié)點(diǎn):" + exe.getActivityId());

信號(hào)事件:xml形式如下

    <signal id="testSignal" name="testSignal"></signal>
    <process id="myProcess" name="My process" isExecutable="true">
        ...
        <intermediateCatchEvent id="signalintermediatecatchevent1"
            name="SignalCatchEvent">
            <signalEventDefinition signalRef="testSignal"></signalEventDefinition>
        </intermediateCatchEvent>
        ...
    </process>

它需要等待程序發(fā)出信號(hào)才能繼續(xù)運(yùn)行,不然就會(huì)在原地等待。

runService.signalEventReceived("testSignal");

消息事件:xml中需要先設(shè)定message標(biāo)簽,再在中間拋出事件中,創(chuàng)建消息事件定義,并使用messageRef屬性執(zhí)行message標(biāo)簽。

    <message id="testMsg" name="testMsg"></message>
    <process id="myProcess" name="My process" isExecutable="true">
        ...
        <intermediateCatchEvent id="messageintermediatecatchevent1"
            name="MessageCatchEvent">
            <messageEventDefinition messageRef="testMsg"></messageEventDefinition>
        </intermediateCatchEvent>
        ...
    </process>

相應(yīng)的程序中也只需要發(fā)出相應(yīng)消息即可工作流繼續(xù)向前進(jìn)行

runService.messageEventReceived("testMsg", exe.getId());

區(qū)別:從信號(hào)和消息的方法參數(shù)就可以看出,信號(hào)的發(fā)送不需要制定特定的對(duì)象,而消息是需要制定流程的。簡(jiǎn)單來說信號(hào)像是廣播,只要定義了該信號(hào)的人都會(huì)收到信號(hào);而消息像私信只有收到消息的目標(biāo)流程才會(huì)繼續(xù)前行。

7.工作的產(chǎn)生和管理

異步任務(wù)產(chǎn)生的工作:下面的應(yīng)用會(huì)使用到activiti引擎的異步執(zhí)行,因此需要在activiti.cfg.xml中進(jìn)行如下配置,開啟異步執(zhí)行,如果不開啟此項(xiàng)配置,流程將會(huì)卡在ServiceTask不能繼續(xù)向前運(yùn)行。

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

之后創(chuàng)建bpmn工作流圖,以xml格式打開,更改他的servicetask組件屬性

<serviceTask id="servicetask1" name="Service Task" activiti:async="true" 
activiti:class="org.crazyit.act.c10.MyJavaDelegate"></serviceTask>

activti:class指向的是他要執(zhí)行的類(類需要實(shí)現(xiàn)JavaDelegate接口并且實(shí)現(xiàn)execute方法),而async屬性則是開啟異步執(zhí)行。

package org.crazyit.act.c10;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;

public class MyJavaDelegate implements JavaDelegate {

    @Override
    public void execute(DelegateExecution arg0) {
        System.out.println("這是處理類");
    }
}

 定時(shí)器任務(wù):會(huì)等待定時(shí)結(jié)束在繼續(xù)執(zhí)行,如下:

        <intermediateCatchEvent id="timerintermediatecatchevent1"
            name="TimerCatchEvent">
            <timerEventDefinition>
                <timeDuration>PT1M</timeDuration>
            </timerEventDefinition>
        </intermediateCatchEvent>

被中斷的任務(wù):被suspend中斷的任務(wù)會(huì)被寫入ACT_RU_SUSPENED表中,同理activate重新激活被中斷的任務(wù),任務(wù)將會(huì)被從表中移除,恢復(fù)正常運(yùn)行。

無法執(zhí)行的任務(wù):加入一個(gè)任務(wù)三次拋出異常,就將會(huì)被加入ACT_RU_DEADLETTER表中。

上述就是小編為大家分享的Activiti的知識(shí)點(diǎn)分析是什么了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI