JBPM工作流(七)——详解流程图
概念:
流程圖的組成:
a.?活動(dòng)?Activity?/?節(jié)點(diǎn)?Node
b.?流轉(zhuǎn)?Transition?/?連線(單向箭頭)
c.?事件
1.流轉(zhuǎn)(Transition)
a)?一般情況一個(gè)活動(dòng)中可以指定一個(gè)或多個(gè)Transition
i.?開(kāi)始活動(dòng)(Start)中只能有一個(gè)Transition。
ii.?結(jié)束活動(dòng)(End)中沒(méi)有Transition。
iii.?其他活動(dòng)中有一條或多條Transition
b)?如果Transition只有一個(gè),則可以不指定名稱(名稱是null);如果有多個(gè),則要分別指定唯一的名稱。
2.活動(dòng)(Activity)
a)?流轉(zhuǎn)控制活動(dòng)(預(yù)定義活動(dòng))
?
?
? ? ? ? ? ? i.?start開(kāi)始活動(dòng)
?
? ? ?代表流程的開(kāi)始邊界,一個(gè)流程有且只能有一個(gè)Start活動(dòng)。開(kāi)始活動(dòng)只能指定一個(gè)Transition。在流程實(shí)例啟動(dòng)后,會(huì)?自動(dòng)的使用這個(gè)唯一的Transition離開(kāi)開(kāi)始活動(dòng),到一下個(gè)活動(dòng)。
ii.?end/end-error/end-cancel(結(jié)束活動(dòng))
代表流程的結(jié)束邊界,可以有多個(gè),也可以沒(méi)有。如果有多個(gè),則到達(dá)任一個(gè)結(jié)束活動(dòng),整個(gè)流程就都結(jié)束了;如果沒(méi) 有,則到達(dá)最后那個(gè)沒(méi)有Transition的活動(dòng),流程就結(jié)束了。
?
? ? ? ? ? ?iii.?state狀態(tài)活動(dòng)
?
?
作用:等待。可以使用signal使其結(jié)束等待,并向后執(zhí)行一步。
? ? ??
?
iv.?task任務(wù)活動(dòng)
?
?
-->個(gè)人任務(wù)的分配
?
1.?使用流程變量:assignee="#{manager}"
2.?AssignmentHandler:assignable.setAssignee(userId);?//?指定當(dāng)前任務(wù)的辦理人(分配任務(wù))
a)?需要在.jbdl.xml的<task>元素中寫(xiě)
?
| 1 | <assignment-handler class="cn.grace.AssignmentHandlerImpl"/> |
b)?指定的AssignmentHandlerImpl類要實(shí)現(xiàn)AssignmentHandler接口
c)?在AssignmentHandlerImpl類中可以使用assignable.setAssignee(userId),分配個(gè)人任務(wù)。
3.?TaskService.assignTask(taskId,?userId)//?把指定的任務(wù)分配給指定的人
?
| 1 | processEngine.getTaskService().assignTask(taskId, userId); |
-->組任務(wù)的分配
1.??使用流程變量:assignee="#{userIdsString}"?//?要是String型的變量,多個(gè)候選人之前用','隔開(kāi)
2. AssignmentHandler:assignable.addCandidateUser(userId);//?添加組任務(wù)的候選人
a)?需要在.jbdl.xml的<task>元素中寫(xiě)
?
| 1 | <assignment-handler class="cn.grace.GroupTaskAssignmentHandlerImpl"/> |
b)?指定的AssignmentHandlerImpl類要實(shí)現(xiàn)AssignmentHandler接口
c)?在AssignmentHandlerImpl類中可以使用assignable.addCandidateUser(userId),添加組任務(wù)候選人。
??3. TaskService.addTaskParticipatingUser(taskId,userId,Participation.CANDIDATE);//添加組任務(wù)的候選人
v.?Decision判斷活動(dòng)
1.?使用expression,如:expr="#{'to?state2'}"
2.?使用Handler,在Handler?Class里配置指定的DecisionHandlerImpl類的路徑
DecisionHandlerImpl.java
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class DecisionHandlerImpl implements DecisionHandler { ????// 計(jì)算離開(kāi)當(dāng)前節(jié)點(diǎn)用的Transition的名稱并返回 ????@Override ????public String decide(OpenExecution execution) { ????????System.out.println("DecisionHandlerImpl.decide()"); ????????// 獲取業(yè)務(wù)數(shù)據(jù) ????????Integer days = (Integer) execution.getVariable("請(qǐng)假天數(shù)"); ????????// 選擇Transition ????????if (days > 7) { ????????????return "to 總經(jīng)理審批"; ????????} else { ????????????return "to end1"; ????????} ????} } |
ProcessTest.java
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Test public void test() { ????// 1,部署流程定義 ????InputStream in = this.getClass().getResourceAsStream("test.jpdl.xml"); // 當(dāng)前類所在包中的文件 ????processEngine.getRepositoryService()// ????????????.createDeployment()// ????????????.addResourceFromInputStream("test.jpdl.xml", in)// ????????????.deploy(); ????// 2,啟動(dòng)流程實(shí)例 ????Map<String, Object> variables = new HashMap<String, Object>(); ????// variables.put("請(qǐng)假天數(shù)", 10);啟動(dòng)流程實(shí)例后,進(jìn)行到to 總經(jīng)理審批環(huán)節(jié)。 ????variables.put("請(qǐng)假天數(shù)", 3);//啟動(dòng)流程實(shí)例后,進(jìn)行到to end1環(huán)節(jié)。 ????ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test", variables); } |
此時(shí),如果variables.put("請(qǐng)假天數(shù)",?3);啟動(dòng)流程實(shí)例后,進(jìn)行到to?end1環(huán)節(jié)。
此時(shí),如果variables.put("請(qǐng)假天數(shù)",?10);啟動(dòng)流程實(shí)例后,進(jìn)行到to?總經(jīng)理審批環(huán)節(jié)。
3.?如果同時(shí)配置了expression與Handler,則expression有效,忽略Handler。
vi.?fork、join分支/聚合活動(dòng)
?
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class ProcessTest { ????private ProcessEngine processEngine = Configuration.getProcessEngine(); ????@Test ????public void test() { ????????// 1,部署流程定義 ????????InputStream in = this.getClass().getResourceAsStream("test.jpdl.xml"); // 當(dāng)前類所在包中的文件 ????????processEngine.getRepositoryService()// ????????????????.createDeployment()// ????????????????.addResourceFromInputStream("test.jpdl.xml", in)// ????????????????.deploy(); ????????// 2,啟動(dòng)流程實(shí)例 ????????ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); ????????System.out.println("processInstanceId = " + pi.getId()); ????????System.out.println("當(dāng)前正在執(zhí)行的活動(dòng):" + pi.findActiveActivityNames()); ????} } |
輸出結(jié)果為:
processInstanceId?=?test.330007
當(dāng)前正在執(zhí)行的活動(dòng):[匯款,?發(fā)貨](méi)
可以看出,匯款和發(fā)貨同時(shí)執(zhí)行中。并且,只有當(dāng)2條路線都到j(luò)oin活動(dòng),流程才會(huì)繼續(xù)往后執(zhí)行。
b)?自定義活動(dòng)(custom)
i.?在<custom>元素中指定class屬性為指定的類ExternalActivityBehaviourImpl
ii.?這個(gè)類要實(shí)現(xiàn)ExternalActivityBehaviour接口,其中有兩個(gè)方法:
1.?execute(ActivityExecution):節(jié)點(diǎn)的功能代碼
2.?signal(ActivityExecution,?String,?Map):在當(dāng)前節(jié)點(diǎn)等待時(shí),外部發(fā)信號(hào)時(shí)的行為
3.?在execute()方法中,可以調(diào)用以下方法對(duì)流程進(jìn)行控制
?
a)?ActivityExecution.waitForSignal():在當(dāng)前節(jié)點(diǎn)等待。 b)?ActivityExecution.takeDefaultTransition():使用默認(rèn)的Transition離開(kāi),當(dāng)前節(jié)點(diǎn)中定義的第一個(gè)為默認(rèn)的。 c)?ActivityExecution.take(String?transitionName):使用指定的Transition離開(kāi) d)?ActivityExecution.end():結(jié)束流程實(shí)例 4.?也可以實(shí)現(xiàn)ActivityBehaviour接口,只有一個(gè)方法execute(ActivityExecution),這樣就不能等待,否則signal時(shí)會(huì)有類轉(zhuǎn)換異常。 ?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class ExternalActivityBehaviourImpl implements ExternalActivityBehaviour { ????// 到達(dá)這個(gè)活動(dòng)時(shí)執(zhí)行的方法 ????@Override ????public void execute(ActivityExecution execution) throws Exception { ????????System.out.println("已發(fā)送信息.");//此處寫(xiě)自己要執(zhí)行的事件 ????????// 默認(rèn)是執(zhí)行完代碼后離開(kāi)當(dāng)前活動(dòng),不會(huì)執(zhí)行signal方法,也可以寫(xiě)如下代碼 ????????// execution.takeDefaultTransition(); // 離開(kāi)當(dāng)前活動(dòng) ????????// // 使用指定名稱的Transition離開(kāi)當(dāng)前活動(dòng) ????????// execution.take(transitionName); ????????// 執(zhí)行完后不要離開(kāi),而是要等待外部調(diào)用signal()方法時(shí)才離開(kāi) ????????execution.waitForSignal(); ????} ????// 調(diào)用signal()方法離開(kāi)當(dāng)前節(jié)點(diǎn)前執(zhí)行的方法(如果在execute()中直接離開(kāi)當(dāng)前節(jié)點(diǎn)了,這個(gè)方法就不會(huì)被執(zhí)行) ????@Override ????public void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) throws Exception { ????????System.out.println("ExternalActivityBehaviourImpl.signal()"); ????} } |
3.事件
a)?在根元素中,或在節(jié)點(diǎn)元素中,使用<on?event="">元素指定事件,其中event屬性代表事件的類型。
b)?在<on>中用子元素<event-listener?class="EventListenerImpl"?/>,指定處理的類,要求指定的類要實(shí)現(xiàn)EventListener接口
c)?事件類型:
i.?<on>元素放在根元素(<process>)中,可以指定event為start或end,表示流程的開(kāi)始與結(jié)束。
ii.?<on>元素放在節(jié)點(diǎn)元素中,可以指定event為start或end,表示節(jié)點(diǎn)的進(jìn)入與離開(kāi)
iii.?在Start節(jié)點(diǎn)中只有end事件,在End節(jié)點(diǎn)中只有start事件。
iv.?在<transition>元素中直接寫(xiě)<event-listener?class="">,就是配置事件。(因?yàn)樵谶@里只有一個(gè)事件,所以不用寫(xiě)on與類型)
v.?在<task>元素中還可以配置assign事件,是在分配任務(wù)時(shí)觸發(fā)的。
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <?xml version="1.0" encoding="UTF-8"?> <process name="test" xmlns="http://jbpm.org/4.4/jpdl"> ????<!-- 流程實(shí)例的啟動(dòng)事件 --> ????<on event="start"> ????????<event-listener class="cn.grace.EventListenerImpl"></event-listener> ????</on> ????<!-- 流程實(shí)例的結(jié)束事件 --> ????<on event="end"> ????????<event-listener class="cn.grace.EventListenerImpl"></event-listener> ????</on> ????<start name="start1" g="86,69,7,1"> ????????<!-- 開(kāi)始活動(dòng)中只有離開(kāi)活動(dòng)的事件 --> ????????<on event="end"> ????????????<event-listener class="cn.grace.EventListenerImpl"></event-listener> ????????</on> ????????<transition name="to task1" to="task1" g="-53,-17" /> ????</start> ????<task name="task1" g="61,171,92,52" assignee="張三"> ????????<!-- 進(jìn)入活動(dòng)的事件 --> ????????<on event="start"> ????????????<event-listener class="cn.grace.EventListenerImpl"></event-listener> ????????</on> ????????<!--離開(kāi)活動(dòng)的事件 --> ????????<on event="end"> ????????????<event-listener class="cn.grace.EventListenerImpl"></event-listener> ????????</on> ????????<transition name="to end1" to="end1" g="-47,-17" /> ????</task> ????<end name="end1" g="86,272,48,48"> ????????<!-- 結(jié)束活動(dòng)中只有進(jìn)入活動(dòng)的事件 --> ????????<on event="start"> ????????????<event-listener class="cn.grace.EventListenerImpl"></event-listener> ????????</on> ????</end> </process> |
根據(jù)上述.jpdl.xml和對(duì)應(yīng)的.png圖,啟動(dòng)流程實(shí)例會(huì)執(zhí)行3次EventListenerImpl事件,結(jié)束流程實(shí)例也會(huì)執(zhí)行3次EventListenerImpl事件。
轉(zhuǎn)載于:https://www.cnblogs.com/HHR-SUN/p/7235878.html
總結(jié)
以上是生活随笔為你收集整理的JBPM工作流(七)——详解流程图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: lr_eval_string()使用
- 下一篇: tcp断开时分几步