jbpm3.2 總結

sz_bdqn發表於2011-07-23
 Java Business Process Management
jBpm 是一個功能強大的可擴充套件的工作流管理系統。
jBPM在2004年10月18日,釋出了2.0版本,並在同一天加入了JBoss,成為了JBoss企業中介軟體平臺的一個組成部分,它的名稱也改成JBoss jBPM。隨著jBPM加入JBoss組織,jBPM也將進入一個全新的發展時代,它的前景是十分光明的。

jBpm用流程語言來表示商業流程的術語比如:任務、非同步通訊的等待狀態、定時器、自動操作等等。把這些操作綁在一起, jBpm就有了強大和易擴充套件的控制流機制。

特點:
jBpm倚賴性很小,可以很容易的作為java庫來使用。可以用在吞吐量極為關鍵的J2EE 群應用伺服器環境中;
jBpm的持久化層用Hibernate實現,可以同任何資料庫配置可以部署在任何應用伺服器上。

jBpm工具箱;
jBpm圖形化流程設計器:圖形設計器是一個Eclipse外掛;它同時支援業務分析員和技術開發人員,這樣就可以在業務流程建模和實際執行之間平滑轉換。

jBpm核心元件:是一個Java庫;處理流程定義和執行時的流程例項執行。可以用在任何java環境(web應用程式,Swing應用程式,EJB等等)。

jBpm控制檯web應用程式:流程執行執行時間任務生成的中央使用者介面;管理和監視控制檯允許檢查和操作執行中的流程例項。

jBpm身份元件:身份驗證。

jBpm排程程式:監視和執行已經計劃到時執行流程的定時器的元件。

jBpm資料庫相容包:包括所有支援資料庫的相關資訊,JDBC驅動程式和資料庫初始化指令碼。

jBpm BPEL擴充套件:獨立的擴充套件包用來支援BPEL(Business Process Execution Language 商業流程執行語言)

流程建模 基本概念(1):
流程定義:基於定向圖表示了一個商業流程的規範。圖由節點和轉換組成,圖中的每個節點都有一個特定的型別,節點型別定義了執行時的行為;流程定義有且只有一個開始狀態。
流程例項:一個流程定義執行的例項,當一個流程例項被建立後,一個令牌也為主要執行路線建立了,這個令牌稱為這個流程例項的根令牌,她的位置處於流程定義的開始狀態。

令牌:
令牌:是執行的一個路線。令牌是執行時概念,用來維護指向圖中某一節點的指標。

訊號:
訊號指示令牌繼續圖執行。當接受到無名的訊號,令牌將用預設的離開轉換離開節點;當轉換名字在訊號中已經指定,令牌將使用指定的轉換離開節點。

動作:
在流程執行中在事件上執行的片段java程式碼。主要事件型別是:(進入節點) entering a node,(離開節點) leaving a node?和(執行轉換)taking a transition。

節點責任:
首先,它可以執行傳統java程式碼;比如:建立一個新的任務例項、傳送一個通知、更新資料庫。
其次,使流程繼續執行。

節點型別:
任務節點(task-node):任務型接點代表一個或多個可以被執行的任務,此類節點需要指定某個人執行;
等待節點(state):是一個單純(bare-bones)等待狀態,等待一個訊號,訊號到達到繼續執行;
條件節點(decision):進行條件判斷;
分支節點(fork):一個分支把一個執行路線分割成多個併發的執行路線;
聯合節點(join):將多個併發路線合併成一個路線;
普通節點(node):當你想在節點裡寫入自己的程式碼時,可以使用普通節點。該型別節點無條件執行。

Transitions(轉換):
轉換具有一個源節點和一個目標節點;
轉換可以有一個任意的名字,但必須是唯一的。

Actions(動作):
Action是一段程式碼,由流程中的時間觸發

Action的程式碼:
public class RemoveEmployeeUpdate implements ActionHandler {
public void execute(ExecutionContext ctx) throws Exception {
    //get the fired employee from the process variables.
    String firedEmployee = (String)
       ctx.getContextInstance().getVariable("fired employee");   
    Connection connection = ctx.getProcessInstance().
       getJbpmSession().getSession().getConnection();
    Statement statement = connection.createStatement();  
    statement.execute("DELETE FROM EMPLOYEE WHERE ...");
    statement.execute();
    statement.close();
}
}

jBPM設計器:
以外掛的形式存在
外掛安裝:
1.將jbpm-designer資料夾複製任意目錄下。
2.在<MyEclipse>\eclipse\links目錄下建立jbpm-gpd.link檔案,輸入下面內容:
path=D:\\Program Files\\MyEclipse 6.0\\jbpm-designer\\jbpm-gpd-feature       (填入jbpm-gpd-feature的絕對目錄即可)

概述(1)
流程定義代表業務流程的正式規範並且基於有向圖。
圖由節點和轉換組成。
圖中的每個節點指定型別。節點型別定義執行時行為。
一個流程定義絕對有一個開始狀態。

概述(2)
令牌(token )是一個執行路徑。一個令牌是維護圖中一個節點指標的執行時概念。
流程例項是一個流程定義的執行。當一個流程例項被建立時,令牌為主執行路徑建立。 這個令牌叫做流程例項的根令牌並且它被放在流程定義的開始狀態上。
在令牌進入節點後,這個節點被執行。節點自己負責圖執行連續。圖執行連續完成後使令牌離開這個節點。每個節點型別為圖執行連續實現 一個不同的行為。不傳播執行的節點將成為狀態節點。

流程圖 :
流程定義的基礎是由節點和轉換組成的圖。那資訊被表達在一個叫prcessdefinition.xml 的xml檔案中。每個節點都有一個型別,如狀態、決策、分支、合併等等,每個節點都有 一系列的離開轉換。為了區分開他們可以給轉換一個名稱。

task-node 節點:
任務(task )節點代表一個或多個將要被人們執行的任務。所以當執行到達任務節點時, 任務例項將在工作流參與者的任務列表中建立。
需要人們的參與該節點才會執行

state-node 節點:
狀態(state)節點是一個最基本的等待狀態。同任務節點的不同是不會在任何任務列表 中建立任務例項。
需要傳送一個訊號(Signal)該節點才會執行。

node節點:
無條件執行

decision 節點:
即為條件節點,根據不同的返回值決定流程的走向


實現方案:
定義一個實現DecisionHandler 介面的類
定義一個表示式#{ }
定義為<transition>指定<condition>子節點,指明條件

fork 節點:
分叉(fork)節點分開一個執行路徑成為多個併發的執行路徑。預設的分叉行為是為每 個離開這個分叉節點的轉換建立一個子令牌(token ),在到達分叉節點時生成和這個令牌的 一個父子關係(parent-child relation)。

join 節點:
預設的,合併(join )假設所有到達合併節點的令牌是同一個父親的孩子。這種情形被建立當使用上面所提及的分叉時建立同且當所有被分叉建立的令牌到達同一個合併時。一個 合併將結束每一個進入合併的令牌。當所有的兄弟令牌已經到達合併時,父令牌將通過“唯 一”的離開轉換被傳播。當仍然有兄弟令牌活動時,合併將扮演一個等待狀態。

轉換(transitions ):
轉換(transitions )有一個源節點和一個目標節點。源節點代表來自(from)屬性,目標節點代表到達(to )屬性。
jBPM 的大部分屬性依賴轉換的命名的唯一性

動作(actions):
動作(actions)是在流程執行裡的事件上執行的java 程式碼片段。

動作可以放在節點和事件上
放在節點上:可以影響控制流
放在事件上:不可以影響控制流

基本的API:
1.JbpmConfiguration:
jBPM流程例項的配置,在流程的執行過程中,需要使用JbpmConfiguration去建立需要的服務。
JbpmConfiguration是執行緒安全的物件,可以使用單例模式建立。
獲取物件:
private static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance([jbpm.cfg.xml]);
主要方法:
public void createSchema(),生成儲存資料的物理表

2.JbpmContext
用於流程的持久化操作。
得到JbpmContext物件
public JbpmContext getContext() {
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if (jbpmContext == null) {
jbpmContext = jbpmConfiguration.createJbpmContext();
}
return jbpmContext;
}

3.JbpmContext的主要方法
public void deployProcessDefinition(ProcessDefinition processDefinition)
釋出流程定義,用於將流processdefinition.xml中的配置資訊儲存到資料庫
public List getTaskList(String actorId)
獲取指定使用者的任務列表
public List getGroupTaskList(List actorIds)
獲取指定使用者組的任務列表
public TaskInstance loadTaskInstance(long taskInstanceId)
根據任務例項ID載入任務例項
public ProcessInstance loadProcessInstance(long processInstanceId)
根據ID載入流程例項
public ProcessInstance newProcessInstance(String processDefinitionName)
根據流程定義的名稱建立最後一個版本的流程例項
public Session getSession()
獲取Hibernate中的Session物件
public void setSession(Session session)
用新的Session代替原來的Session(Hibernate)
public Connection getConnection()
獲取連線物件
public String getActorId()
獲取當前ActorId
public void setActorId(String actorId)
設定新的ActorId
public void close()
關閉,該操作能將資料提交到資料庫

4.ProcessDefinition
表示流程定義的物件模型
得到該物件的方法:
如果物件模型未存在:ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource(“simple/processdefinition.xml”);將流程定義的圖模型轉化成物件模型
如果物件模型已存在:ProcessDefinition processDefinition = JbpmContext.getGraphSession().findLatestProcessDefinition("simple");
如果是一zip檔案:public static ProcessDefinition parseParZipInputStream(ZipInputStream zipInputStream),這個方法方便使用者通過頁面釋出流程,釋出後的資料儲存在jbpm_bytearray表和jbpm_byteblock表中

5.ProcessInstance
流程例項
得到流程例項的兩種方法
根據流程定義物件:ProcessInstance processInstance = new ProcessInstance(processDefinition)
根據流程定義名稱:ProcessInstance processInstance = JbpmContext.newProcessInstance("simple")
根據ID獲取流程例項:ProcessInstance processInstance = JbpmContext.getProcessInstance(id);

6.ProcessInstance的主要方法
public void signal():傳送一個訊號,對於state-node有效
public boolean hasEnded():判斷流程例項是否有效
processInstance.getRootToken().getNode().getName():獲取當前節點的名稱
public long getId():獲取流程例項的ID

7.TaskMgmtInstance
工作管理員例項,用於管理任務節點(task-node)
方法
public Collection getTaskInstances():獲取管理的所有任務例項

8.TaskInstance
任務例項,需要人的參與
獲取該物件
public TaskInstance loadTaskInstance(long taskInstanceId):根據任務例項ID載入任務例項
public List<TaskInstance> getTaskList(String actorId):獲取指定使用者所擁有的當前可用任務列表
public List<TaskInstance>   getGroupTaskList(List actorIds):獲取指定使用者組所擁有的當前可用任務列表

9.TaskInstance的主要方法
public List<Transition> getAvailableTransitions():獲取任務中可用的Transition集合
public void addVariables(Map variables):新增變數,變數在xml檔案中配置
public Map getVariables():得到變數
public void end(Transition transition) public void end(String transitionName) public void end() 結束當前的任務並進入下一個節點
taskInstance.getTaskMgmtInstance().getProcessInstance():獲取當前任務所在的流程例項

10.GraphSession
專門用於對流程定義和流程例項操作的Session
主要方法
public List findProcessInstances(long processDefinitionId):根據流程定義ID獲取該流程的所有流程例項
public ProcessDefinition loadProcessDefinition(long processDefinitionId):根據ID載入流程定義
public ProcessDefinition findLatestProcessDefinition(String name):根據名字找到最後版本的流程定義
public List findAllProcessDefinitions():找到所有的流程定義
public void deleteProcessDefinition(long processDefinitionId):根據ID刪除流程定義
public ProcessInstance loadProcessInstance(long processInstanceId):根據ID載入流程例項

11.TaskMgmtSession
管理任務的Session
方法
public List findTaskInstances(String actorId):查詢指定使用者的任務例項列表
public List findTaskInstances(String[] actorIds):查詢多個使用者的任務例項列表
public List findPooledTaskInstances(String actorId):一個任務分配給多個執行人時使用
public List findPooledTaskInstances(List actorIds):同上
public TaskInstance loadTaskInstance(long taskInstanceId):根據ID獲取任務例項
public List findTaskInstancesByIds(List taskInstanceIds):同上,但是可以指定多個ID

基本操作
實現思路:
1、根據配置資訊建立各種服務和物件
2、獲取jbpm上下文
3、釋出流程[每次修改流程後都要執行執行]
4、驅動節點
5、處理任務
一個流程定義包含多個流程例項,一個流程例項包含一個工作管理員,一個工作管理員包含了所有任務例項。

參見:http://hi.baidu.com/suny_duan/blog/item/bdefc30ecca6dd246159f376.html

資料處理
1、流程資料
每一個流程例項都能儲存相關資料,這些資料與指定流程繫結
將資料與流程例項繫結
ProcessInstance.setContextInstance(“名稱”,”值”)
從流程例項中讀取資料
ProcessInstance.getContextInstance(“名稱”)

2.任務資料
可以為每個任務例項繫結相關資料,併為資料指定訪問許可權
訪問許可權有:
read,required
read,write,required
read,write
read
write

3、業務資料
業務資料是與業務邏輯相關的資料,比如請假資料,報銷資料。
業務資料往往要和流程資料或任務資料建立連線。儲存業務資料的ID即可。

常見介面:
1.ActionHandler:
org.jbpm.graph.def.ActionHandler
定義一個自定義動作類,實現該介面即可
方法
public void execute(ExecutionContext context) throws Exception {
System.out.println("審批完畢!");
}

2.AssignmentHandler:
org.jbpm.taskmgmt.def.AssignmentHandler
為任務指定執行人
方法
public void assign(Assignable assignable, ExecutionContext executionContext)throws Exception {
assignable.setActorId("張三");//指定一個執行人
assignable.setPooledActors(new String[]{"李四", "王八"});//指定一組執行人
}

3.DecisionHandler:
org.jbpm.graph.node.DecisionHandler
自定義條件類,在<decision><handler class=“”></handler></ decision>中指定
方法
public String decide(ExecutionContext executionContext) throws Exception {
if(true){
return "執行路徑1";
}else{
return "執行路徑2";
}
}