這篇文章主要講解了“怎么用jBPM實(shí)現(xiàn)Hello World”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“怎么用jBPM實(shí)現(xiàn)Hello World”吧!
成都創(chuàng)新互聯(lián)長(zhǎng)期為超過千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為東烏珠穆沁企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作,東烏珠穆沁網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
在開始之前,首先下載和安裝jBPM。
jBPM包含一個(gè)圖形設(shè)計(jì)器工具,可用于創(chuàng)建在這些范例中顯示的xml文件。你可以在《下載和安裝jBPM》部分找到下載這個(gè)圖形設(shè)計(jì)器的指南。你不需要為了完成本教程而使用這個(gè)圖形設(shè)計(jì)工具。
Hello World范例
流程定義是一個(gè)有向圖,由節(jié)點(diǎn)(node)和轉(zhuǎn)移(transition)組成。Hello world流程有三個(gè)節(jié)點(diǎn)。為了看到這些代碼片段如何組合在一起,我們從一個(gè)簡(jiǎn)單的流程開始,不使用圖形設(shè)計(jì)工具。下面的圖顯示hello world流程的圖形表示:
圖 3.1. Hello world流程圖
public void testHelloWorldProcess() { // 本方法顯示一個(gè)流程定義和此流程定義的執(zhí)行。這個(gè)流程定義有三個(gè)節(jié)點(diǎn):一個(gè)未命名的 // start狀態(tài),一個(gè)狀態(tài)s和一個(gè)名為end的結(jié)束狀態(tài)。 // 下面一行將一段xml文本解析為一個(gè)流程定義ProcessDefinition。流程定義是對(duì)流程 // 的正式描述,表示為一個(gè)Java對(duì)象。 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "" + " " ); // 下面一行代碼創(chuàng)建流程定義的一個(gè)執(zhí)行。流程執(zhí)行創(chuàng)建之后將擁有一個(gè)主執(zhí)行 // 路徑(=根token),指向開始狀態(tài)節(jié)點(diǎn)。 ProcessInstance processInstance = new ProcessInstance(processDefinition); // 流程執(zhí)行創(chuàng)建之后,擁有一個(gè)主執(zhí)行路徑(=根token)。 Token token = processInstance.getRootToken(); // 流程執(zhí)行創(chuàng)建之后,主執(zhí)行路徑指向流程定義的開始狀態(tài)節(jié)點(diǎn)。 assertSame(processDefinition.getStartState(), token.getNode()); // 下面我們啟動(dòng)流程執(zhí)行,從缺省轉(zhuǎn)移路線離開開始狀態(tài)節(jié)點(diǎn)。 token.signal(); // signal方法將阻塞,直至流程執(zhí)行進(jìn)入一個(gè)等待狀態(tài)。 // 流程執(zhí)行進(jìn)入了第一個(gè)等待狀態(tài):狀態(tài)s。所以主執(zhí)行路徑現(xiàn)在指向狀態(tài)s。 assertSame(processDefinition.getNode("s"), token.getNode()); // 下面我們發(fā)送第二個(gè)信號(hào)。這將恢復(fù)流程執(zhí)行,通過缺省的轉(zhuǎn)移路徑離開狀態(tài)s。 token.signal(); // 現(xiàn)在signal方法返回了,因?yàn)榱鞒虒?shí)例到達(dá)了結(jié)束狀態(tài)節(jié)點(diǎn)。 assertSame(processDefinition.getNode("end"), token.getNode()); }" + " " + "" + " " + " " + "" + " " + "
數(shù)據(jù)庫(kù)范例
jBPM的一個(gè)基本特征是把處于等待狀態(tài)中的流程執(zhí)行持久化到數(shù)據(jù)庫(kù)中的能力。下面的范例將向你展示如何將一個(gè)流程實(shí)例保存到j(luò)BPM數(shù)據(jù)庫(kù)中。本范例也暗示存在一個(gè)流程執(zhí)行的上下文。下面各個(gè)方法在不同的用戶代碼片段中創(chuàng)建,例如,在web應(yīng)用程序中的一段用戶代碼發(fā)起一個(gè)流程執(zhí)行并將它持久化到數(shù)據(jù)庫(kù)中,隨后,一個(gè)消息驅(qū)動(dòng)bean從數(shù)據(jù)庫(kù)中裝載這個(gè)流程實(shí)例并恢復(fù)其執(zhí)行。
public class HelloWorldDbTest extends TestCase { static JbpmConfiguration jbpmConfiguration = null; static { // 像此處的范例配置文件能夠在'src/config.files'中找到。典型地配置信息存在 // 于資源文件'jbpm.cfg.xml'中,但在這里我們直接傳遞一個(gè)XML字符串形式的配置信息。 // 首先我們創(chuàng)建一個(gè)JbpmConfiguration靜態(tài)對(duì)象。系統(tǒng)中的所有線程可以使用 // 同一個(gè)JbpmConfiguration,因此我們可以安全地把它設(shè)定為靜態(tài)的。 jbpmConfiguration = JbpmConfiguration.parseXmlString( "" + // jbpm-context機(jī)制能夠從jbmp使用的環(huán)境服務(wù)中分離出jbpm核心引擎。 " " ); } public void setUp() { jbpmConfiguration.createSchema(); } public void tearDown() { jbpmConfiguration.dropSchema(); } public void testSimplePersistence() { // 在以下的三個(gè)方法調(diào)用之間,所有的數(shù)據(jù)通過數(shù)據(jù)庫(kù)傳遞。在這個(gè)單元測(cè)試中, // 這三個(gè)方法是順序執(zhí)行的,因?yàn)槲覀円獪y(cè)試一個(gè)完整的流程場(chǎng)景。但是在現(xiàn)實(shí) //中,這些方法代表對(duì)" + " " + // 同樣地,jbpm使用的所有資源文件可以從jbpm.cfg.xml中引用。 "" + " " + " " + " " + " " + " " + " " + " " + " 任務(wù)分配范例
在下面的例子中我們展示如何將任務(wù)分配給用戶。因?yàn)閖BPM工作流引擎和組織機(jī)構(gòu)模型的分離,一個(gè)用于計(jì)算參與者(actor)的表達(dá)式語(yǔ)言總是太受限了。因此,你必須指定一個(gè) AssignmentHandler接口的實(shí)現(xiàn)類來(lái)包含計(jì)算任務(wù)的參與者的過程。
public void testTaskAssignment() { // 下面的流程基于hello world流程。狀態(tài)節(jié)點(diǎn)被任務(wù)節(jié)點(diǎn)取代。任務(wù)節(jié)點(diǎn)是jPDL中 // 的一種節(jié)點(diǎn),表示一個(gè)等待狀態(tài),并創(chuàng)建在流程繼續(xù)執(zhí)行之前必須完成的任務(wù)。 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "" + " " ); // 創(chuàng)建流程定義的一個(gè)執(zhí)行實(shí)例。 ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); // 下面開始流程執(zhí)行,從缺省轉(zhuǎn)換路徑離開開始狀態(tài)。 token.signal(); // signal方法將阻塞,直至流程執(zhí)行進(jìn)入一個(gè)等待狀態(tài)。在這里,就是任務(wù)節(jié)點(diǎn)t。 assertSame(processDefinition.getNode("t"), token.getNode()); // 當(dāng)流程執(zhí)行到達(dá)任務(wù)節(jié)點(diǎn),一個(gè)'換尿布(change nappy)'任務(wù)將被創(chuàng)建, // NappyAssignmentHandler被調(diào)用以決定把這個(gè)任務(wù)分配給誰(shuí)。 // NappyAssignmentHandler返回'(爸爸)papa'。 // 在真實(shí)的環(huán)境中,任務(wù)通過org.jbpm.db.TaskMgmtSession類中的方法從數(shù)據(jù) // 庫(kù)中取得。因?yàn)槲覀儾幌朐诒痉独邪志没膹?fù)雜性,我們僅僅從流程實(shí)例中 // 取出第一個(gè)任務(wù)實(shí)例(我們知道在這個(gè)測(cè)試場(chǎng)景中只有一個(gè)任務(wù)實(shí)例)。 TaskInstance taskInstance = (TaskInstance) processInstance .getTaskMgmtInstance() .getTaskInstances() .iterator().next(); // 現(xiàn)在,我們檢測(cè)任務(wù)實(shí)例是否真正被指派給'papa'. assertEquals("papa", taskInstance.getActorId() ); // 現(xiàn)在我們假設(shè)爸爸已經(jīng)完成他的任務(wù),并把任務(wù)標(biāo)記為已完成。 taskInstance.end(); // 因?yàn)檫@是最后(唯一)一個(gè)要完成的任務(wù),這個(gè)任務(wù)的完成出發(fā)了流程實(shí)例的繼續(xù)執(zhí)行。 assertSame(processDefinition.getNode("end"), token.getNode()); }" + " " + "" + " " + " " + "" + " " + "" + " " + " " + " 定制action范例
action是把你的客戶java代碼綁定到j(luò)BPM流程的一種機(jī)制。action能夠關(guān)聯(lián)到它自己的節(jié)點(diǎn)(如果它們?cè)诹鞒痰膱D形表示中是相關(guān)的的話)。action也能夠放置在事件(例如進(jìn)入轉(zhuǎn)換、離開節(jié)點(diǎn)、進(jìn)入節(jié)點(diǎn)等)之中。在這種情況下,action不是流程的圖形表示的一部分,但是,當(dāng)運(yùn)行時(shí)流程執(zhí)行觸發(fā)了這些事件的時(shí)候,這些action將被執(zhí)行。
// MyActionHandler代表一個(gè)能夠在jBPM流程執(zhí)行過程中執(zhí)行某些用戶代碼的類。 public class MyActionHandler implements ActionHandler { // 在每個(gè)test之前(在setUp方法中), isExecuted成員將被設(shè)置為false。 public static boolean isExecuted = false; // action將把 isExecuted設(shè)置為true,使得單元測(cè)試能夠顯示action在什么時(shí)候被執(zhí)行。 public void execute(ExecutionContext executionContext) { isExecuted = true; } }我們從在下面的范例中將要用到的action實(shí)現(xiàn):MyActionHandler開始。這個(gè)action處理器實(shí)現(xiàn)沒有做真正有用的工作,僅僅把布爾變量isExecuted設(shè)置為true。變量isExecuted是靜態(tài)的,所以能夠同時(shí)從action處理器內(nèi)部和要校驗(yàn)它的值的action中訪問。
// 每個(gè)測(cè)試將在開始時(shí)設(shè)置MyActionHandler的靜態(tài)成員isExecuted為false。 public void setUp() { MyActionHandler.isExecuted = false; }下面的例子顯示同樣的action,但是現(xiàn)在action被分別放在enter-node和leave-node事件之中。請(qǐng)注意與轉(zhuǎn)換只有一個(gè)事件不同,節(jié)點(diǎn)擁有多個(gè)事件類型,因此被放置到節(jié)點(diǎn)中的action應(yīng)該放在event元素之中。
public void testTransitionAction() { // 下面的流程是hello world流程的一個(gè)變體。我們把一個(gè)action加入從狀態(tài)s到結(jié)束狀 // 態(tài)的轉(zhuǎn)換之中。本測(cè)試的目的是顯示要把java代碼集成到j(luò)BPM流程中是多么容易。 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "" + " " ); // 啟動(dòng)流程定義的一個(gè)新的執(zhí)行實(shí)例。 ProcessInstance processInstance = new ProcessInstance(processDefinition); // 下一個(gè)信號(hào)將導(dǎo)致執(zhí)行離開開始狀態(tài),到達(dá)狀態(tài)s。 processInstance.signal(); // 這里我們顯示 MyActionHandler還沒有被執(zhí)行。 assertFalse(MyActionHandler.isExecuted); // ... 以及主執(zhí)行路徑指向狀態(tài)s assertSame(processDefinition.getNode("s"), processInstance.getRootToken().getNode()); // 下一個(gè)信號(hào)將觸發(fā)根token的執(zhí)行。該token將取得包含action的轉(zhuǎn)換, // 該action將在調(diào)用signal方法的過程中執(zhí)行。 processInstance.signal(); // 這里我們可以看到在signal方法被調(diào)用的時(shí)候, MyActionHandler被執(zhí)行了。 assertTrue(MyActionHandler.isExecuted); }" + " " + "" + " " + " " + "" + " " + "" + " " + " ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "" + " " ); ProcessInstance processInstance = new ProcessInstance(processDefinition); assertFalse(MyActionHandler.isExecuted); // 下一個(gè)信號(hào)將導(dǎo)致流程執(zhí)行離開開始狀態(tài),進(jìn)入狀態(tài)s。因此狀態(tài)s被進(jìn)入,action被執(zhí)行。 processInstance.signal(); assertTrue(MyActionHandler.isExecuted); // 重置MyActionHandler.isExecuted。 MyActionHandler.isExecuted = false; // 下一個(gè)信號(hào)將觸發(fā)流程執(zhí)行離開狀態(tài)s,因此action將被再次執(zhí)行。 processInstance.signal(); // 瞧…… assertTrue(MyActionHandler.isExecuted);" + " " + "" + " " + " " + "" + " " + "" + " " + " " + "" + " " + " " + " 感謝各位的閱讀,以上就是“怎么用jBPM實(shí)現(xiàn)Hello World”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)怎么用jBPM實(shí)現(xiàn)Hello World這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
網(wǎng)頁(yè)標(biāo)題:怎么用jBPM實(shí)現(xiàn)HelloWorld
轉(zhuǎn)載來(lái)源:http://weahome.cn/article/jcjdei.html