Activiti第二篇【管理流程定义、执行任务和流程实例、流程变量】
tags: Activiti
上篇Activiti只是一個快速入門案例,這篇就講定義、部署、查看任務等等的一些細節【涉及到的數據庫表、對象等等】...
管理流程定義
管理流程定義主要涉及到以下的4張表:
-- 流程部署相關的表 SELECT * FROM act_ge_bytearray # 通用字節資源表SELECT * FROM act_ge_property # 通用屬性表,可以生成部署idSELECT * FROM act_re_deployment #部署表SELECT * FROM act_re_procdef # 流程定義表 復制代碼PNG資源
在Eclipse中Activiti插件會自動生成一個BPMN與之對應的PNG圖片,是需要通過加載PNG圖片的
public void deploy() {//獲取倉庫服務 :管理流程定義RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deploy = repositoryService.createDeployment()//創建一個部署的構建器.addClasspathResource("LeaveActiviti.bpmn")//從類路徑中添加資源,一次只能添加一個資源.name("請求單流程")//設置部署的名稱.category("辦公類別")//設置部署的類別.deploy();System.out.println("部署的id"+deploy.getId());System.out.println("部署的名稱"+deploy.getName());} 復制代碼而我們的Intellij idea插件不會自動生成PNG圖片,但是我們在加載BPMN文件的時候,好像會自動插入PNG圖片,數據庫是有對應的記錄的【我們是沒有手動加載PNG圖片資源的】
我們查看一下
//查看bpmn 資源圖片public void viewImage() throws Exception{String deploymentId="201";String imageName=null;//取得某個部署的資源的名稱 deploymentIdList<String> resourceNames = processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId);// buybill.bpmn buybill.pngif(resourceNames!=null&&resourceNames.size()>0){for(String temp :resourceNames){if(temp.indexOf(".png")>0){imageName=temp;}}}/*** 讀取資源* deploymentId:部署的id* resourceName:資源的文件名*/InputStream resourceAsStream = processEngine.getRepositoryService().getResourceAsStream(deploymentId, imageName);//把文件輸入流寫入到文件中File file=new File("d:/"+imageName);FileUtils.copyInputStreamToFile(resourceAsStream, file);} 復制代碼可惜的是,查看出來的圖片的中文數據會亂碼...
查看流程定義
我們當時候查詢流程定義是通過我們設置流程圖的id來查看的....其實我們可以通過其他的屬性來查詢...并且可以查詢出更加詳細的數據
//查看流程定義public void queryProcessDefination(){String processDefiKey="buyBill";//流程定義key//獲取流程定義列表List<ProcessDefinition> list = processEngine.getRepositoryService().createProcessDefinitionQuery()//查詢 ,好比where // .processDefinitionId(proDefiId) //流程定義id// 流程定義id : buyBill:2:704 組成 : proDefikey(流程定義key)+version(版本)+自動生成id.processDefinitionKey(processDefiKey)//流程定義key 由bpmn 的 process 的 id屬性決定 // .processDefinitionName(name)//流程定義名稱 由bpmn 的 process 的 name屬性決定 // .processDefinitionVersion(version)//流程定義的版本.latestVersion()//最新版本//排序.orderByProcessDefinitionVersion().desc()//按版本的降序排序//結果 // .count()//統計結果 // .listPage(arg0, arg1)//分頁查詢.list();//遍歷結果if(list!=null&&list.size()>0){for(ProcessDefinition temp:list){System.out.print("流程定義的id: "+temp.getId());System.out.print("流程定義的key: "+temp.getKey());System.out.print("流程定義的版本: "+temp.getVersion());System.out.print("流程定義部署的id: "+temp.getDeploymentId());System.out.println("流程定義的名稱: "+temp.getName());}}} 復制代碼資源來自ZIP
我們還可以加載的是ZIP類型的資源數據
//部署流程定義,資源來自zip格式public void deployProcessDefiByZip(){InputStream in=getClass().getClassLoader().getResourceAsStream("BuyBill.zip");Deployment deploy = processEngine.getRepositoryService().createDeployment().name("采購流程").addZipInputStream(new ZipInputStream(in)).deploy();System.out.println("部署名稱:"+deploy.getName());System.out.println("部署id:"+deploy.getId());} 復制代碼刪除流程定義
//刪除流程定義public void deleteProcessDefi(){//通過部署id來刪除流程定義String deploymentId="101";processEngine.getRepositoryService().deleteDeployment(deploymentId);}復制代碼再次查詢的時候,已經沒有101這個流程定義的數據了。
流程實例與任務執行
流程實例與任務執行的常用表有以下幾個:
-- 流程實例與任務SELECT * FROM act_ru_execution # 流程執行對象信息 SELECT * FROM act_ru_task # 正在運行的任務表SELECT * FROM act_hi_procinst # 歷史流程實例表 SELECT * FROM act_hi_taskinst # 歷史流程任務表復制代碼這里就簡單簡述一下流程實例與流程對象的區別:
- (1)如果是單例流程,執行對象ID就是流程實例ID
- (2)如果一個流程有分支和聚合,那么執行對象ID和流程實例ID就不相同
- (3)一個流程中,流程實例只有1個,執行對象可以存在多個。
開始流程##
public void startProcess(){String processDefiKey="leaveActiviti";//bpmn 的 process id屬性ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processDefiKey);System.out.println("流程執行對象的id:"+pi.getId());//Execution 對象System.out.println("流程實例的id:"+pi.getProcessInstanceId());//ProcessInstance 對象System.out.println("流程定義的id:"+pi.getProcessDefinitionId());//默認執行的是最新版本的流程定義} 復制代碼查看正在運行的任務
//查詢正在運行任務 public void queryTask(){//取得任務服務TaskService taskService = processEngine.getTaskService();//創建一個任務查詢對象TaskQuery taskQuery = taskService.createTaskQuery();//辦理人的任務列表List<Task> list = taskQuery.list();//遍歷任務列表if(list!=null&&list.size()>0){for(Task task:list){System.out.println("任務的辦理人:"+task.getAssignee());System.out.println("任務的id:"+task.getId());System.out.println("任務的名稱:"+task.getName());}}} 復制代碼查詢SELECT * FROM act_ru_task 表
獲取流程實例的狀態
有的時候,我們需要判斷它是在該流程,還是該流程已經結束了。我們可以根據獲取出來的對象是否為空來進行判斷
//獲取流程實例的狀態public void getProcessInstanceState(){String processInstanceId="605";ProcessInstance pi = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();//返回的數據要么是單行,要么是空 ,其他情況報錯//判斷流程實例的狀態if(pi!=null){System.out.println("該流程實例"+processInstanceId+"正在運行... "+"當前活動的任務:"+pi.getActivityId());}else{System.out.println("當前的流程實例"+processInstanceId+" 已經結束!");}}復制代碼查看歷史流程實例的信息
//查看歷史執行流程實例信息public void queryHistoryProcInst(){List<HistoricProcessInstance> list = processEngine.getHistoryService().createHistoricProcessInstanceQuery().list();if(list!=null&&list.size()>0){for(HistoricProcessInstance temp:list){System.out.println("歷史流程實例id:"+temp.getId());System.out.println("歷史流程定義的id:"+temp.getProcessDefinitionId());System.out.println("歷史流程實例開始時間--結束時間:"+temp.getStartTime()+"-->"+temp.getEndTime());}}} 復制代碼查詢表:
查看歷史實例執行任務信息
public void queryHistoryTask(){String processInstanceId="605";List<HistoricTaskInstance> list = processEngine.getHistoryService().createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).list();if(list!=null&&list.size()>0){for(HistoricTaskInstance temp:list){System.out.print("歷史流程實例任務id:"+temp.getId());System.out.print("歷史流程定義的id:"+temp.getProcessDefinitionId());System.out.print("歷史流程實例任務名稱:"+temp.getName());System.out.println("歷史流程實例任務處理人:"+temp.getAssignee());}}} 復制代碼給予對應的實例id就可以查詢出執行到哪個任務了...
執行任務
根據任務的id,就可以把該任務執行了。
public void compileTask(){String taskId="608";//taskId:任務idprocessEngine.getTaskService().complete(taskId);System.out.println("當前任務執行完畢");}復制代碼流程變量
流程變量涉及到的數據庫表:
act_ru_variable:正在執行的流程變量表 act_hi_varinst:流程變量歷史表復制代碼流程變量在工作流中扮演著一個非常重要的角色。例如:請假流程中有請假天數、請假原因等一些參數都為流程變量的范圍**。流程變量的作用域范圍是只對應一個流程實例**。也就是說各個流程實例的流程變量是不相互影響的。流程實例結束完成以后流程變量還保存在數據庫中(存放到流程變量的歷史表中)。
設置流程變量
我們有兩種服務可以設置流程變量,TaskService【任務服務】和RuntimeService【運行時服務】
場景
- 在流程開始的時候設置流程變量
- 在完成某個任務的時候設置流程變量
- 使用TaskService設置服務
- 使用RuntimeService設置服務
作用:
- 傳遞業務參數
- 動態指定代理人【我們快速入門的例子是固定在流程定義圖上寫上代理人的】
- 指定連接【決定流程往哪邊走】
流程變量支持類型
如果我們使用JavaBean來作為流程的變量,那么我們需要將JavaBean實現Serializable接口。
Javabean類型設置獲取流程變量,除了需要這個javabean實現了Serializable接口外,還要求流程變量對象的屬性不能發生變化,否則拋出異常。解決方案,固定序列化ID
setVariable和setVariableLocal的區別
例子
//模擬流程變量設置public void getAndSetProcessVariable(){//有兩種服務可以設置流程變量 // TaskService taskService = processEngine.getTaskService(); // RuntimeService runtimeService = processEngine.getRuntimeService();/**1.通過 runtimeService 來設置流程變量* executionId: 執行對象* variableName:變量名* values:變量值*/ // runtimeService.setVariable(executionId, variableName, values); // runtimeService.setVariableLocal(executionId, variableName, values);//設置本執行對象的變量 ,該變量的作用域只在當前的execution對象 // runtimeService.setVariables(executionId, variables); //可以設置多個變量 放在 Map<key,value> Map<String,Object>/**2. 通過TaskService來設置流程變量* taskId:任務id*/ // taskService.setVariable(taskId, variableName, values); // taskService.setVariableLocal(taskId, variableName, values); 設置本執行對象的變量 ,該變量的作用域只在當前的execution對象 // taskService.setVariables(taskId, variables); //設置的是Map<key,values>/**3. 當流程開始執行的時候,設置變量參數* processDefiKey: 流程定義的key* variables: 設置多個變量 Map<key,values>*/ // processEngine.getRuntimeService() // .startProcessInstanceByKey(processDefiKey, variables)/**4. 當任務完成時候,可以設置流程變量* taskId:任務id* variables: 設置多個變量 Map<key,values>*/ // processEngine.getTaskService().complete(taskId, variables);/** 5. 通過RuntimeService取變量值* exxcutionId: 執行對象* */ // runtimeService.getVariable(executionId, variableName);//取變量 // runtimeService.getVariableLocal(executionId, variableName);//取本執行對象的某個變量 // runtimeService.getVariables(variablesName);//取當前執行對象的所有變量/** 6. 通過TaskService取變量值* TaskId: 執行對象* */ // taskService.getVariable(taskId, variableName);//取變量 // taskService.getVariableLocal(taskId, variableName);//取本執行對象的某個變量 // taskService.getVariables(taskId);//取當前執行對象的所有變量} 復制代碼//設置流程變量值public void setVariable(){String taskId="1804";//任務id//采用TaskService來設置流程變量//1. 第一次設置流程變量 // TaskService taskService = processEngine.getTaskService(); // taskService.setVariable(taskId, "cost", 1000);//設置單一的變量,作用域在整個流程實例 // taskService.setVariable(taskId, "申請時間", new Date()); // taskService.setVariableLocal(taskId, "申請人", "何某某");//該變量只有在本任務中是有效的//2. 在不同的任務中設置變量 // TaskService taskService = processEngine.getTaskService(); // taskService.setVariable(taskId, "cost", 5000);//設置單一的變量,作用域在整個流程實例 // taskService.setVariable(taskId, "申請時間", new Date()); // taskService.setVariableLocal(taskId, "申請人", "李某某");//該變量只有在本任務中是有效的/*** 3. 變量支持的類型* - 簡單的類型 :String 、boolean、Integer、double、date * - 自定義對象bean */TaskService taskService = processEngine.getTaskService();//傳遞的一個自定義bean對象AppayBillBean appayBillBean=new AppayBillBean();appayBillBean.setId(1);appayBillBean.setCost(300);appayBillBean.setDate(new Date());appayBillBean.setAppayPerson("何某某");taskService.setVariable(taskId, "appayBillBean", appayBillBean);System.out.println("設置成功!");} 復制代碼//查詢流程變量public void getVariable(){String taskId="1804";//任務id // TaskService taskService = processEngine.getTaskService(); // Integer cost=(Integer) taskService.getVariable(taskId, "cost");//取變量 // Date date=(Date) taskService.getVariable(taskId, "申請時間");//取本任務中的變量 Date date=(Date) taskService.getVariableLocal(taskId, "申請時間");//取本任務中的變量 // String appayPerson=(String) taskService.getVariableLocal(taskId, "申請人");//取本任務中的變量 String appayPerson=(String) taskService.getVariable(taskId, "申請人");//取本任務中的變量 // // System.out.println("金額:"+cost); // System.out.println("申請時間:"+date); // System.out.println("申請人:"+appayPerson);//讀取實現序列化的對象變量數據TaskService taskService = processEngine.getTaskService();AppayBillBean appayBillBean=(AppayBillBean) taskService.getVariable(taskId, "appayBillBean");System.out.println(appayBillBean.getCost());System.out.println(appayBillBean.getAppayPerson());}復制代碼 public class AppayBillBean implements Serializable{private Integer id;private Integer cost;//金額private String appayPerson;//申請人private Date date;//申請日期public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getCost() {return cost;}public void setCost(Integer cost) {this.cost = cost;}public String getAppayPerson() {return appayPerson;}public void setAppayPerson(String appayPerson) {this.appayPerson = appayPerson;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}} 復制代碼總結
- 流程定義涉及到了四張數據庫表
- 我們可以通過API把我們的流程定義圖讀取出來
- 可以根據查詢最新版本的流程定義
- 刪除流程定義
- 部署流程定義的時候也可以是ZIP文件
- 流程在運行中,涉及到兩個對象,四張數據庫表:
- 流程實例
- 流程任務
- 流程實例可以有多個,流程對象只能有一個。
- 如果流程沒有分支的話,那么流程實例就等于流程對象
- 基于這么兩個對象,我們就可以做很多事情了
- 獲取流程實例和任務的歷史信息
- 判斷流程實例是否為空來判斷流程是否結束了
- 查看正在運行服務的詳細信息
- 通過流程實例來開啟流程
- 流程變量:它涉及到了兩張表。流程變量實際上就是我們的條件。
- 流程變量的作用域只在流程實例中。
- 我們可以在流程開始的時候設置流程變量,在任務完成的時候設置流程變量。
- 運行時服務和流程任務都可以設置流程變量。
如果您覺得這篇文章幫助到了您,可以給作者一點鼓勵
總結
以上是生活随笔為你收集整理的Activiti第二篇【管理流程定义、执行任务和流程实例、流程变量】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对BFC的一点认识
- 下一篇: 纳税服务系统八【系统、子系统首页】