UFLO是一套基于JAVA的流程引擎,它即可以用在基于J2EE的B/S系統(tǒng)之上,也可以用于基于J2EE的C/S系統(tǒng)之中。所以UFLO在設(shè)計之初就不與任何UI表現(xiàn)層綁定,它所要做的就是提供一系列的可供外部調(diào)用的API接口,對于我們的業(yè)務(wù)系統(tǒng)而言,可以調(diào)用UFLO中提供的API,實現(xiàn)業(yè)務(wù)流程的開啟、任務(wù)的開始與完成等操作。
我們知道,UFLO中有三個子項目,分別是uflo-core、uflo-console與uflo-client。uflo-core提供了流程運行的核心環(huán)境,負責整個流程生命周期的管理工作;uflo-console則是一個基于dorado7表現(xiàn)層的分支項目,這個項目中提供了B/S項目中基于dorado7的流程模版控制與測試中心、提供了用戶待辦頁面及節(jié)假日配置等流程引擎運行的輔助模塊;最后一個uflo-client則是提供給我們的程序員使用的,通過調(diào)用uflo-client模塊中的ProcessClient與其中的TaskClient就可實現(xiàn)在我們的業(yè)務(wù)系統(tǒng)與流程引擎的交互。下面是開啟一個流程實例操作的代碼片段。
開啟流程示例代碼
import javax.annotation.Resource; import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.service.StartProcessInfo;
public class BusinessTest { @Resource(name=ProcessClient.BEAN_ID) private ProcessClient processClient;
public void saveDataAndStartProcess(BusinessData data){ String primaryKeyValue=saveBusinessData(data); StartProcessInfo info=new StartProcessInfo(ContextHolder.getLoginUserName()); info.setBusinessId(primaryKeyValue); processClient.startProcessById(101, info); }
}
從上面的代碼中可以看到,在開始流程之前,我們首先將提交上業(yè)的BusinessData這個業(yè)務(wù)數(shù)據(jù)對象保存,保存后產(chǎn)生該對象的主鍵值primaryKeyValue,接下來創(chuàng)建一個StartProcessInfo對象,將業(yè)務(wù)對象主鍵值賦給這個對象,并設(shè)置流程開啟人,最后調(diào)用ProcessClient接口的ProcessInstance startProcessById(longprocessId,StartProcessInfostartProcessInfo)方法開啟一個ID為101的流程模版對應(yīng)的流程實例。在上面的代碼當中,ProcessClient我們通過Spring注入到當前類中,ProcessClient配置在Spring中的Bean的ID就是ProcessClient.BEAN_ID的常量值,所以這里可以直接使用。
下面我們再來看一段完成任務(wù)的業(yè)務(wù)代碼:import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.service.StartProcessInfo;
public class BusinessTest { @Resource(name=TaskClient.BEAN_ID) private TaskClient taskClient;
public void saveDataAndStartProcess(BusinessData data,long taskId){ saveBusinessData(data); Map<String,Object> variables=new HashMap<String,Object>(); variables.put("businessName", data.getName()); variables.put("businessOwner", data.getBusinessOwner());
taskClient.start(taskId);
taskClient.complete(taskId,variables);
}
}
比較開始流程的代碼片段,我們會發(fā)現(xiàn)操作模式基本一樣,都是先進行業(yè)務(wù)數(shù)據(jù)操作(保存、更新之類),再進行流程操作(開始流程實例或完成任務(wù)),在這段完成任務(wù)的示例代碼當中,首先調(diào)用saveBusinessData方法來保存提交上來的業(yè)務(wù)數(shù)據(jù),接下來創(chuàng)建一個Map集合,用于存放需要寫入流程的流程變量的值,這里的我們從BusinessData中取了兩個值放入這個Map,接下來調(diào)用TaskClient的start方法開始指定的人工任務(wù)(UFLO中人工任務(wù)的完成必須要先開始,某些時候?qū)τ谔幚碇芷诒容^長的人工任務(wù),可以先開始,再不斷設(shè)置處理進度progress的值,最后再完成,這里就直接開始后完成),最后調(diào)用TaskClient的complete方法完成指定人工任務(wù)并回將流程變量的Map寫入到流程實現(xiàn)。
同開始流程的代碼一樣,TaskClient也是通過Spring注入,其在Spring中Bean的ID為TaskClient.BEAN_ID。
前面提到,UFLO的使用支持嵌入式與獨立服務(wù)兩種方式,但對于我們程序員來說,它只需要使用uflo-client模塊中的ProcessClient與其中的TaskClient與我們的業(yè)務(wù)系統(tǒng)交互即可,究竟項目做好之后,采用哪種部署方式,我們的uflo-client模塊中的ProcessClient與其中的TaskClient都可以通過設(shè)置一個外部屬性實現(xiàn)自由轉(zhuǎn)換,這個屬性就是uflo.restAccessBaseUrl,該屬性值的作用就是指定獨立部署的遠程ufloserver的地址。默認該屬性值為空,那么我們的引擎就會認為我們采用的是嵌入式模式,所以它會通過訪問我們項目內(nèi)部配置的數(shù)據(jù)源實現(xiàn)與流程引擎數(shù)據(jù)庫的互動;一旦我們定義了該屬性的值,那么UFLO引擎就知道我們采用的是獨立服務(wù)模式,它會通過該屬性定義的URL值來訪問遠程的uflo server,實現(xiàn)本地業(yè)務(wù)邏輯與遠程流程引擎的交互。
ProcessClient對于我們程序員來說,主要是實現(xiàn)業(yè)務(wù)流程的開啟、流程模版與實例的刪除、流程模版與變量的獲取等操作;而TaskClient則提供了大量針對人工任務(wù)的操作。在這兩個接口當中,我們?yōu)槊總€方法都添加了詳細的注釋,使用時查看注釋應(yīng)該就可以明確具體用法。
在項目當中,如果我們需要查詢流程流轉(zhuǎn)相關(guān)歷史信息,那么可以通過HistoryService來實現(xiàn)。在HistoryService當中提供了大量的與流程相關(guān)的歷史信息查詢功能,比如根據(jù)流程實例的ID查詢當前實例流轉(zhuǎn)過程當中經(jīng)過了哪些流程節(jié)點,或者根據(jù)流程實例查詢當前實例流轉(zhuǎn)時產(chǎn)生了哪些人工任務(wù),這些人工任務(wù)在處理時處理人是誰,所有者是誰,花費多長時間等。同樣HistoryService也配置在Spring當中,其bean的ID為“uflo.historyService”,我們的業(yè)務(wù)系統(tǒng)可根據(jù)需要調(diào)用這個HistoryService查詢所需要的歷史流程信息。
更多建議: