日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

JBPM 之介绍,使用

發(fā)布時(shí)間:2023/12/15 综合教程 23 生活家
生活随笔 收集整理的這篇文章主要介紹了 JBPM 之介绍,使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

JBPM,全稱(chēng)是Java Business Process Management(業(yè)務(wù)流程管理),它是覆蓋了業(yè)務(wù)流程管理、工作流、服務(wù)協(xié)作等領(lǐng)域的一個(gè)開(kāi)源的、靈活的、易擴(kuò)展的可執(zhí)行流程語(yǔ)言框架。jBPM是公開(kāi)源代碼項(xiàng)目,它使用要遵循 Apache License,。

  jBPM在2004年10月18日,發(fā)布了2.0版本,并在同一天加入了JBoss,成為了JBoss企業(yè)中間件平臺(tái)的一個(gè)組成部分,它的名稱(chēng)也改成JBoss jBPM。隨著jBPM加入JBoss組織,jBPM也將進(jìn)入一個(gè)全新的發(fā)展時(shí)代,它的前景是十分光明的。

  jBPM最大的特色就是它的商務(wù)邏輯定義沒(méi)有采用目前的一些規(guī)范,如WfMC, XPDL, BPML, ebXML, BPEL4WS等,而是采用了它自己定義的JBoss jBPM Process definition language (jPdl)。jPdl認(rèn)為一個(gè)商務(wù)流程可以被看作是一個(gè)UML狀態(tài)圖。jPdl就是詳細(xì)定義了這個(gè)狀態(tài)圖的每個(gè)部分,如起始、結(jié)束狀態(tài),狀態(tài)之間的轉(zhuǎn)換,過(guò)圖型化的流程定義,直觀地描述業(yè)務(wù)流程。

  jBPM的另一個(gè)特色是它使用Hibernate來(lái)管理它的數(shù)據(jù)庫(kù)。Hibernate是目前Java領(lǐng)域最好的一種數(shù)據(jù)存儲(chǔ)層解決方案,只要是 Hibernate 支持的數(shù)據(jù)庫(kù), jBPM 也就支持.過(guò)Hibernate,jBPM將數(shù)據(jù)的管理職能分離出去,自己專(zhuān)注于商務(wù)邏輯的處理。

JBPM由于各個(gè)版本之間差異比較大,所以在晚上找的很多資料跟自己使用的情況并不相符,很難找到一個(gè)完整的,能夠運(yùn)行的例子(Web程序例子)。

本文以jbpm-starters-kit-3.1.2版本為例。下載地址:http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/j/project/jb/jbpm/jBPM%203/jbpm-3.1.2/。請(qǐng)下載:jbpm-starters-kit-3.1.2.zip版本,網(wǎng)上的參考資料比較多。
OK,我們接下來(lái)討論JBPM的流程圖

上圖是一個(gè)比較完整的JBPM流程圖(Finance中的子流程未寫(xiě))。

上圖的XML定義代碼:

為方便大家Copy,所有代碼均不顯示行號(hào)

<?xml version="1.0" encoding="UTF-8"?>
<process-definition
name="simple">
<start-state name="start">
<description>This process's name is simple</description>
<task name="fill reimburse">
<controller>
<variable name="baoxiaoId" access="read,write,required" mapped-name="報(bào)銷(xiāo)ID"/>
</controller>
</task>
<transition name="" to="Manager"></transition>
</start-state>
<task-node name="Manager">
<task name="department audit">
<controller>
<variable name="baoxiaoId" access="read" mapped-name="報(bào)銷(xiāo)ID"/>
</controller>
<assignment class="com.workflow.hander.ManagerAssignment"/>
</task>
<transition name="approve" to="AutoDecide"></transition>
<transition name="requiremodify" to="Modify"></transition>
<transition name="unapprove" to="Message"></transition>
</task-node>
<decision name="AutoDecide">
<handler class="com.workflow.hander.ProcessDecision"/>
<transition name="&lt;10000" to="Finance"></transition>
<transition name="&gt;10000" to="Boss"></transition>
</decision>
<task-node name="Boss">
<task name="boss audit">
<controller>
<variable name="baoxiaoId" access="read" mapped-name="報(bào)銷(xiāo)ID"/>
</controller>
<assignment class="com.workflow.hander.BossAssignment"/>
</task>
<transition name="approve" to="Finance"></transition>
<transition name="unapprove" to="Message"></transition>
</task-node>
<process-state name="Finance">
<sub-process name="finance"/>
<variable name="baoxiaoId" access="read" mapped-name="報(bào)銷(xiāo)ID"/>
<transition name="reimburse" to="Message"></transition>
</process-state>
<task-node name="Modify">
<task name="modify reimburse">
<controller>
<variable name="baoxiaoId" access="read,write,required" mapped-name="報(bào)銷(xiāo)ID"/>
</controller>
<assignment class="com.workflow.hander.UserAssignment"/>
</task>
<transition name="modified" to="Manager"></transition>
<transition name="cancel" to="Message"></transition>
</task-node>
<node name="Message">
<event type="node-enter">
<action class="com.workflow.hander.ProcessResultAction"/>
</event>
<transition name="" to="end1"></transition>
</node>
<end-state name="end1"></end-state>
</process-definition>

涉及到的Java Handler:

View Code

//在start完成之后觸發(fā)此Handler
public class ManagerAssignment implements AssignmentHandler {

public void assign(Assignable assignable, ExecutionContext executionContext)
throws Exception {

List<TbUser> list=new TbUserDAO().findByUserType(1);
String [] manager=new String[list.size()];
int i=0;
for (Iterator<TbUser> iter = list.iterator(); iter.hasNext();) {
TbUser el = (TbUser)iter.next();
manager[i++]=el.getUserId()+"";
}
assignable.setPooledActors(manager);
}

}
//在Manager審批完成之后(approve)觸發(fā)此Handler
public class ProcessDecision implements DecisionHandler {

public String decide(ExecutionContext executionContext) throws Exception {

String baixiaoId=executionContext.getContextInstance().getVariable("baoxiaoId").toString();
TbBaoxiao baoxiao=new TbBaoxiaoDAO().findById(new Integer(Integer.parseInt(baixiaoId)));
Set<TbBaoXiaoItem> bxItem=baoxiao.getTbBaoXiaoItems();
int count=0;
for (Iterator<TbBaoXiaoItem> iter = bxItem.iterator(); iter.hasNext();) {
TbBaoXiaoItem item = (TbBaoXiaoItem) iter.next();
count+=Integer.parseInt(item.getItemMoney());
}
if(count>10000)
{
return ">10000";
}
return "<10000";
}

}
//在 Decision判斷之后>1000時(shí)觸發(fā)此Handler
public class BossAssignment implements AssignmentHandler {

public void assign(Assignable assignable, ExecutionContext executionContext)
throws Exception {

List<TbUser> list=new TbUserDAO().findByUserType(2);
String [] boss=new String[list.size()];
int i=0;
for (Iterator<TbUser> iter = list.iterator(); iter.hasNext();) {
TbUser el = (TbUser) iter.next();
boss[i++]=el.getUserId()+"";
}
assignable.setPooledActors(boss);
}
}
//Manager審批unapprove時(shí)出發(fā)的Handler
public class UserAssignment implements AssignmentHandler {

private static final long serialVersionUID = 1L;

public void assign(Assignable assignable, ExecutionContext executionContext)
throws Exception {

String issueUser = executionContext.getContextInstance().getVariable("issueUser").toString();
assignable.setActorId(issueUser);
}

}
//所有task結(jié)束之后觸發(fā)此Handler給創(chuàng)建者發(fā)送Message,然后end
public class ProcessResultAction implements ActionHandler {

public void execute(ExecutionContext executionContext) throws Exception {

String baoxiaoId=executionContext.getContextInstance().getVariable("baoxiaoId").toString();
TbBaoxiaoDAO baoxiaoDao=new TbBaoxiaoDAO();
TbBaoxiao baoxiao=baoxiaoDao.findById(new Integer(Integer.parseInt(baoxiaoId)));
String issueUser=baoxiao.getTbUser().getUserName();
baoxiao.setBaoxiaoDate(new Date());

List<TbApprove> list=new TbApproveDAO().findByApproveByBaoxiaoId(baoxiao.getBaoxiaoId());
String result="駁回";
if(list.iterator().hasNext())
{
TbApprove tbapp=(TbApprove) list.iterator().next();
result=tbapp.getApproveResult();
}
baoxiao.setBaoxiaoFlag((result.indexOf("不同意")!=-1?"駁回":"批準(zhǔn)"));
baoxiaoDao.merge(baoxiao);
StringBuffer message=new StringBuffer();
message.append(issueUser+":您好! ");
message.append("您申請(qǐng)的"+baoxiao.getBaoxiaoTitle());
message.append("已經(jīng)被"+(result.indexOf("不同意")!=-1?"駁回":"批準(zhǔn)"));

Message msg=new TextMessage(message.toString());
msg.setDestination(issueUser);
msg.setToken(executionContext.getProcessInstance().getRootToken());

DbMessageService msgService=new DbMessageService();
msgService.send(msg);
msgService.close();
}
}

使用的數(shù)據(jù)表(除了JBPM自身以外的表):

View Code

CREATE TABLE tb_approve (approve_id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER, baoxiao_id INTEGER, approve_result VARCHAR(30), approve_memo VARCHAR(300), approve_date DATETIME, PRIMARY KEY (approve_id));
CREATE TABLE tb_baoxiao (baoxiao_id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER, baoxiao_title VARCHAR(30), baoxiao_memo VARCHAR(30), baoxiao_date DATETIME, baoxiao_flag VARCHAR(30), PRIMARY KEY (baoxiao_id));
CREATE TABLE tb_baoxiao_item (item_id INTEGER NOT NULL AUTO_INCREMENT, baoxiao_id INTEGER, item_name VARCHAR(30), item_money VARCHAR(100), PRIMARY KEY (item_id));
CREATE TABLE tb_user (user_id INTEGER NOT NULL AUTO_INCREMENT, user_name VARCHAR(30), user_password VARCHAR(30), user_type INTEGER, PRIMARY KEY (user_id));
ALTER TABLE tb_approve ADD INDEX FKD0C46A7C5C89B0A (baoxiao_id), ADD CONSTRAINT FKD0C46A7C5C89B0A FOREIGN KEY (baoxiao_id) REFERENCES tb_baoxiao (baoxiao_id);
ALTER TABLE tb_approve ADD INDEX FKD0C46A7CD355B42A (user_id), ADD CONSTRAINT FKD0C46A7CD355B42A FOREIGN KEY (user_id) REFERENCES tb_user (user_id);
ALTER TABLE tb_baoxiao ADD INDEX FKEC067E1ED355B42A (user_id), ADD CONSTRAINT FKEC067E1ED355B42A FOREIGN KEY (user_id) REFERENCES tb_user (user_id);
ALTER TABLE tb_baoxiao_item ADD INDEX FKE2F5D8945C89B0A (baoxiao_id), ADD CONSTRAINT FKE2F5D8945C89B0A FOREIGN KEY (baoxiao_id) REFERENCES tb_baoxiao (baoxiao_id);

/*
-- test Data
insert into tb_user(user_name,user_password,user_type)
values('test','123',0);

insert into tb_user(user_name,user_password,user_type)
values('manager1','123',1);

insert into tb_user(user_name,user_password,user_type)
values('manager2','123',1);
insert into tb_user(user_name,user_password,user_type)
values('boss','123',2);

insert into tb_user(user_name,user_password,user_type)
values('caiwu','123',2);
*/

以上資料具體的action和dao處理我就不貼代碼了,直接說(shuō)怎么進(jìn)入下一個(gè)task。

View Code

Start、End state是JBPM其實(shí)和結(jié)束狀態(tài)的兩個(gè)必不可少的Node。

task-node

  一個(gè)task-node可以包含一個(gè)或多個(gè)task,這些task分配給特定的user。當(dāng)流程執(zhí)行到task-node時(shí),taskinstance將會(huì)被創(chuàng)建,一個(gè)task對(duì)應(yīng)一個(gè)taskinstance。taskinstances創(chuàng)建后,task-node就處于等待狀態(tài)。當(dāng)所有的taskinstances被特定的user執(zhí)行完畢后,將會(huì)發(fā)出一個(gè)新的signal到token,即流程繼續(xù)執(zhí)行。

state

  state是一個(gè)純粹的waitstate(等待狀態(tài))。它和task-node的區(qū)別就是它不會(huì)創(chuàng)建taskinstances。很典型的用法是,當(dāng)進(jìn)入這個(gè)節(jié)點(diǎn)時(shí)(通過(guò)綁定一個(gè)action到node-enterevent),發(fā)送一條消息到外部的系統(tǒng),然后流程就處于等待狀態(tài)。外部系統(tǒng)完成一些操作后返回一條消息,這個(gè)消息觸發(fā)一個(gè)signal到token,然后流程繼續(xù)執(zhí)行。(不常用)

decision

  當(dāng)需要在流程中根據(jù)不同條件來(lái)判斷執(zhí)行不同路徑時(shí),就可以用decision節(jié)點(diǎn)。兩種方法:最簡(jiǎn)單的是在transitions里增加conditionelements(條件),condition是beanshellscript寫(xiě)的,它返回一個(gè)boolean。當(dāng)運(yùn)行的時(shí)候,decision節(jié)點(diǎn)將會(huì)在它的leavingtransitions里循環(huán),同時(shí)比較leavingtransitions里的condition,最先返回'true'的condition,那個(gè)leavingtransitions將會(huì)被執(zhí)行;作為選擇,你可以實(shí)現(xiàn)DecisionHandler接口,它有一個(gè)decide()方法,該方法返回一個(gè)String(leavingtransition的名字)。

fork

  fork節(jié)點(diǎn)把一條執(zhí)行路徑分離成多條同時(shí)進(jìn)行(并發(fā))的執(zhí)行路徑,每條離開(kāi)fork節(jié)點(diǎn)的路徑產(chǎn)生一個(gè)子token。

join

  默認(rèn)情況下,join節(jié)點(diǎn)會(huì)認(rèn)為所有到達(dá)該節(jié)點(diǎn)的token都有著相同的父token。join節(jié)點(diǎn)會(huì)結(jié)束每一個(gè)到達(dá)該節(jié)點(diǎn)的token,當(dāng)所有的子token都到達(dá)該節(jié)點(diǎn)后,父token會(huì)激活。當(dāng)仍然有子token處于活動(dòng)狀態(tài)時(shí),join節(jié)點(diǎn)是waitstate(等待狀態(tài))。

node

  node節(jié)點(diǎn)就是讓你掛自己的action用的(注意:不是event觸發(fā)!!),當(dāng)流程到達(dá)該節(jié)點(diǎn)時(shí),action會(huì)被執(zhí)行。你的action要實(shí)現(xiàn)ActionHandler接口。同樣,在你的action里要控制流程!

歡迎加入我的QQ群(JAVA開(kāi)發(fā)):216672921,

總結(jié)

以上是生活随笔為你收集整理的JBPM 之介绍,使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。