今天是jBPM的第二天,內(nèi)容不多,定義不少,主要講了流程變量,節(jié)點(diǎn)和事件等知識(shí),全是新的知識(shí),剛學(xué)肯定生疏,久了就沒(méi)問(wèn)題了,編程嘛,多敲代碼,多
調(diào)試,才是王道。
1. 流程變量
通過(guò)org.jbpm.context.exe.ContextInstance來(lái)操
作變量。
2.變量的生命周期
變量的訪問(wèn)和賦值是在某一個(gè)token上進(jìn)行的,缺省時(shí),是基于root
Token。每個(gè)Token(執(zhí)行路線)有它自己的一套流程變量。變量的作用域和所屬的Token的生命周期一致,不同的Token上的同名變量互不影
響。
3.變量值要求
變量名的類型為java.lang.String,支持的變量值類型如下(文檔10.1節(jié))。(
如
果變量值是classes that are persistable with
hibernate,則POJO的id應(yīng)為long型或String型。
saveOrUpdate( po );
savePoIdAndPoClassAsVariable()
session.get(
class, id )
節(jié)點(diǎn)
1.
流程圖中的各種節(jié)點(diǎn)的作用及用法
為什么需要多種節(jié)點(diǎn)類型?
需要有不同類型(作用)的節(jié)點(diǎn),才能設(shè)計(jì)出復(fù)雜的流程圖。
Jbpm有一套預(yù)先定義好的節(jié)點(diǎn)類型。如果不夠用,也可以使用自定義節(jié)點(diǎn)進(jìn)行擴(kuò)展,以完成不同的流程的需要。
不同的節(jié)點(diǎn)類型代表不同的行
為。
每個(gè)流程都必須要有開(kāi)始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)。
2.預(yù)定義節(jié)點(diǎn)
start-state,開(kāi)始節(jié)點(diǎn):標(biāo)識(shí)流
程開(kāi)始、
end-state,結(jié)束節(jié)點(diǎn):標(biāo)識(shí)流程結(jié)束、
task-node,任務(wù)節(jié)點(diǎn):可以放0個(gè)或多個(gè)任務(wù)、
decision,
決策節(jié)點(diǎn):路徑選擇,只使用一個(gè)流轉(zhuǎn)(叉路口)、
fork/join,分支節(jié)點(diǎn)/合并節(jié)點(diǎn):可以分為多個(gè)并行執(zhí)行的分支、
state,狀
態(tài)節(jié)點(diǎn):等待。
每個(gè)節(jié)點(diǎn)都對(duì)應(yīng)一個(gè)類(Jbpm的持久化類),都是org.jbpm.graph.def.Node的子類。節(jié)點(diǎn)
都有名字、流轉(zhuǎn)(end-state除外)。
event事件
事
件。
1, 有幾種事件,分別在什么時(shí)候觸發(fā)
2, 怎么指定當(dāng)事件觸發(fā)時(shí)做什么事(Action)
1, 節(jié)點(diǎn)的事件
a)
進(jìn)入節(jié)點(diǎn)(node-enter)。(開(kāi)始節(jié)點(diǎn)沒(méi)有)
b) 離開(kāi)節(jié)點(diǎn)(node-leave)。(結(jié)束節(jié)點(diǎn)沒(méi)有)
2,
流轉(zhuǎn)的事件
a) 只有一個(gè):使用流轉(zhuǎn)(take a transition)
3, 任務(wù)的事件
a)
創(chuàng)建任務(wù)(task-create)
b) 分配任務(wù)(task-assign)
c)
開(kāi)始任務(wù)(task-start)à TaskInstance.start()
d) 結(jié)束任務(wù)(task-end)à
TaskInstance.end()
每個(gè)事件有一個(gè)動(dòng)作(action)清單。當(dāng)jBPM引擎產(chǎn)生一個(gè)事件,動(dòng)作(action)清單就會(huì)被
執(zhí)行. 不同的節(jié)點(diǎn)支持的事件類型不同,是由event元素所在的節(jié)點(diǎn)的類型決定的,例如transition只有一個(gè)事件。
可以在event元
素用可以指定一個(gè)動(dòng)作,當(dāng)指定的事件發(fā)生時(shí),這個(gè)動(dòng)作被執(zhí)行。
可以給同一個(gè)事件指定多個(gè)動(dòng)作,當(dāng)這個(gè)事件觸發(fā)的時(shí)候,這些動(dòng)作執(zhí)行的順序
和定義先后順序是一致的。
不同元素支持不同的事件類型:
一般的節(jié)點(diǎn)都具有的事件:node-enter,進(jìn)入節(jié)點(diǎn)、
node-leave,離開(kāi)節(jié)點(diǎn);
start-state只有node-leave;
end-state只有node-enter;
transition
只有一個(gè)執(zhí)行轉(zhuǎn)換的事件(taking a transition)。因?yàn)橹挥幸粋€(gè)事件,所以配置時(shí)不用寫(xiě)event元素,而直接配置Action。
task
有task-create,任務(wù)創(chuàng)建、task-assign,任務(wù)分配、task-start,任務(wù)開(kāi)始、task-end,任務(wù)結(jié)束。
關(guān)
于哪些元素支持哪些事件,可以通過(guò)文檔的18.4節(jié)中的xml文件的寫(xiě)法中獲得。
如果配置的事件類型不存在,不會(huì)報(bào)錯(cuò),也不會(huì)執(zhí)行。
注
意:在事件中定義的動(dòng)作(Action)不應(yīng)該(不能)影響流程的執(zhí)行。即不要在事件的動(dòng)作中給token發(fā)信號(hào),否則會(huì)拋異常:token is
locked。(在Node中配置的Action可以給Token發(fā)信號(hào)。)
事件執(zhí)行的順序:
已觸發(fā)事件:node-leave
已觸發(fā)事件:transition
已
觸發(fā)事件:node-enter
已觸發(fā)事件:task-create
已觸發(fā)事件:task-assign
已
觸發(fā)事件:task-start
已觸發(fā)事件:task-end
*************************
動(dòng)態(tài)的創(chuàng)建不確定數(shù)量的任務(wù)實(shí)例 *********
會(huì)簽。
實(shí)現(xiàn)任務(wù)分配給多個(gè)人,在流程定義中定義的相
應(yīng)的任務(wù),不指定參與者,也不知道指定為誰(shuí)。需要做以下工作:
1,
阻止jBPM自動(dòng)創(chuàng)建任務(wù)實(shí)例(設(shè)置task-node的create-tasks="false")
2,
在node-enter事件中定義一個(gè)動(dòng)作指定用于創(chuàng)建TaskInstance的類。
類
CreateTaskInstancesAction要接管兩個(gè)操作:創(chuàng)建與分配任務(wù)實(shí)例。
創(chuàng)建任務(wù)實(shí)例要調(diào)用方法:
TaskMgmtInstance.createTaskInstance(Task, ExecutionContext);
其中的
Task 是任務(wù)的定義,可以先得到當(dāng)前的節(jié)點(diǎn):
TaskNode taskNode = (TaskNode)
executionContext.getNode();
然后通過(guò)任務(wù)的名字得到任務(wù)的定義:
Task task =
taskNode.getTask("審批");
任務(wù)分配
個(gè)人任務(wù):actor-id=”xxx”
查詢組任務(wù)列表的方法為:
TaskMgmtSession.findPooledTaskInstances(String
actorId)
對(duì)于一個(gè)組任務(wù),如果他的actorId為null,組中所
有的用戶都可以在組任務(wù)列表中看到這個(gè)任務(wù)。如果使用TaskInstance.setActorId(String)方法設(shè)置這個(gè)任務(wù)由指定的
acrorId來(lái)辦理,這時(shí)pooledActors中的其他人就看不到這個(gè)任務(wù)了,就是說(shuō)actorId會(huì)屏蔽pooledActors;
當(dāng)這個(gè)用戶因某些原因不能辦理任務(wù)時(shí),可以把這個(gè)任務(wù)再退回到組任務(wù)列表中,方法是調(diào)用TaskInstance.setActorId(null)設(shè)置
actorId為null,這時(shí)pooledActors中的所有人又都可以看到這個(gè)任務(wù)了。
不管使用哪種方式分配任務(wù),參與者
(Actor-id,字符串類型)的計(jì)算(確定)都是由業(yè)務(wù)層負(fù)責(zé)解釋的。
最后湯兄給我們推薦了一些好書(shū),學(xué)習(xí)java必須準(zhǔn)備三樣: 心態(tài),基礎(chǔ),睡覺(jué)。能學(xué)多少學(xué)多少。明天才是OA工作流項(xiàng)目的開(kāi)始!加油。。。
posted @
2010-02-01 21:59 d66380022|
編輯 收藏
JBPM與OA
項(xiàng)目
哈
哈,今天終于要開(kāi)始做項(xiàng)目了,心情特別好,在第一天中湯兄讓我們先明白了什么是工作流,怎樣很好的解決這一類問(wèn)題等,接著來(lái)了個(gè)Helloworld,就入門(mén)了。每天都在學(xué)習(xí),每天都有收獲,感覺(jué)真好。還要再提一下,OA(辦公自動(dòng)化)主要技術(shù)之一就是工作流,好,還是仔細(xì)總結(jié)一下一天所學(xué):
1. 工作流就是工
作流程的計(jì)算機(jī)化。
流程(OA),數(shù)量多,隨時(shí)更改
網(wǎng)購(gòu):提交訂單—>配貨—>發(fā)貨—>收貨—>付款
當(dāng)我們想增加、修改流程時(shí),而不想編程則需要用到工作流引擎,由它負(fù)責(zé)判斷下一步
做什么。下圖是它的原理:
狀態(tài)機(jī) +if
else
2. 工作流要解決的主要問(wèn)題是:為實(shí)現(xiàn)某個(gè)業(yè)務(wù)目
標(biāo),在多個(gè)參與者之間,利用計(jì)算機(jī),按某種預(yù)定規(guī)則自
動(dòng)傳遞文檔、信息或者任務(wù)。
通俗的說(shuō),就是多個(gè)人在一起合作完成某件事情。
接下來(lái)是jBPM介紹
3.jBPM介紹
jBPM全稱是Java
Business Process Management。是一種基于J2EE的輕量級(jí)工作流管理系統(tǒng),jBPM是公開(kāi)源
代碼項(xiàng)目。
官方主頁(yè)http://labs.jboss.com/
下載地址:http://labs.jboss.com/jbossjbpm
最重要的還是接下來(lái)的jBPM的使用
4.Jbpm的使用
server:提供的一個(gè)執(zhí)行、測(cè)試工作流和平臺(tái)(Web應(yīng)用程序)。
流程圖是一個(gè)有向圖,由兩部分組成:節(jié)點(diǎn)和流轉(zhuǎn)。節(jié)點(diǎn)有各種各樣形狀(代表各種各
樣的作用)。流轉(zhuǎn)就是指單箭頭,代表從一個(gè)節(jié)點(diǎn)到下一個(gè)節(jié)點(diǎn)。
此文件的約束就是 jPDL。
在jPDL中,不同
的節(jié)點(diǎn),就用不同的標(biāo)簽。
1.xml文件名必須為:processdefinition.xml。
2.必須要在一個(gè)zip文件的根目
錄中。
3.可以有一個(gè)名為processimage.jpg的文件,是流程圖。
應(yīng)用myEclipse設(shè)
計(jì)流程圖步驟:
1.裝jbpm-jpdl-3.2.2插件:
找到jbpm-jpdl-3.2.2下的designer路
徑復(fù)制一下,注意路徑中不能有中文
2.之后在桌面上myEclipse快
捷方式,點(diǎn)右鍵,查找目標(biāo),找到myEclipse安裝目錄,再其下的links目錄下
加入a.link文件
(a可以隨意寫(xiě)),內(nèi)容為
path=粘貼
注意里路徑變?yōu)殡p斜線,之后關(guān)閉myEclipse,再打開(kāi)就OK了。
3.在myEclipse下新建介紹java工程,在src下,新建Process
Definition點(diǎn)下一步,為Process
name :起個(gè)名,比如HelloWorld
。。。。
4,啟動(dòng)服務(wù)器:server/start.bat
5,訪問(wèn):http://localhost:8080/jbpm-console,登陸后,點(diǎn)Deploy,下圖:

6.將zip文件部署
7.點(diǎn)Deploy
8.點(diǎn)start
9.點(diǎn)tokens
后點(diǎn)singal,后在其下點(diǎn)singal
10.點(diǎn)tasks,點(diǎn)start ,按部就班搞定
注意事項(xiàng):
1.怎么從開(kāi)始節(jié)點(diǎn)往下走?Tokens
à Signal(只點(diǎn)一次)
2.怎么沒(méi)有properties窗口?Window
à Show
View à
Properties
3.怎么一點(diǎn)Signal,就結(jié)束了呢?沒(méi)有在Task-Node中
定義任務(wù)吧。要說(shuō)明任務(wù)名稱與任務(wù)的執(zhí)行者。
4.點(diǎn)擊Process
Image,在圖片上沒(méi)有一個(gè)正在運(yùn)
行的標(biāo)志,而且在上方還有一個(gè)錯(cuò)誤提示?把節(jié)點(diǎn)的名稱改為英文,重新Deploy就可
以了。
Jboss Server所在的路徑中不能有
中文或特殊
字符(如&,有的在文件夾jbpm&oa中,這樣就不行),否則不能運(yùn)行
Token的解釋:流程實(shí)例通過(guò)Token的維護(hù)
當(dāng)前正在執(zhí)行的節(jié)點(diǎn)
入門(mén)程序:
HelloWorld
1, 設(shè)計(jì)流程定義à
打包為zip文件(流程
定義文檔,說(shuō)明par的格式要
求)
2, 部署流程定義à
把工作流交給工
作流管理系統(tǒng)保存起來(lái)。只需要執(zhí)行一次,一般是管理員進(jìn)行操作。
3, 執(zhí)行流程à
多個(gè)操作:
a)
啟動(dòng)(創(chuàng)建)流程實(shí)例(Signal)
b)
獲取任務(wù)列表(只是自已的任務(wù)實(shí)
例列表)
c)
辦理任務(wù)
i.
開(kāi)始任務(wù)
ii.
結(jié)束任務(wù)
今天就這么多了,明天再寫(xiě)!
posted @
2010-01-31 23:36 d66380022|
編輯 收藏
今天繼續(xù)講的是lucene
的分詞器,湯兄先回顧了昨天的所學(xué)內(nèi)容,很好。今天講了lucene
的細(xì)節(jié),比如分詞器和高亮器,以及高級(jí)搜索等功能的實(shí)現(xiàn)框架Compass
,案例是傳智的貼吧搜索功能的實(shí)現(xiàn),用的當(dāng)然也是lucene
。
全文檢索(Lucene
)的深入
分詞器:對(duì)文本資源進(jìn)行切分,將文本按規(guī)則切
分為一個(gè)個(gè)可以進(jìn)行索引的最小單位(關(guān)鍵詞)。
某文檔中的一段文本,經(jīng)過(guò)分詞后如下:
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
在
|
Internet
|
上
|
采集
|
信息
|
的
|
軟件
|
被
|
叫做
|
爬蟲(chóng)
|
或
|
蜘蛛
|
。
|
建立索引和進(jìn)行搜索時(shí)都要用到分詞器。為了保證能正確的搜索到結(jié)果,在建立索引
與進(jìn)行搜索時(shí)使用的分詞器應(yīng)是同一個(gè)。
全文檢索不區(qū)分大小寫(xiě)
對(duì)于中文分詞,通常有三種方式:單字分詞、二分法分詞、詞典分詞。
最好的分詞器:詞庫(kù)分詞
高亮器:
1.作用:
1.截取摘要(大小)
2.高亮關(guān)鍵字(前綴
后綴)
2.怎么用:
過(guò)濾器
Filter
RangeFilter,可以對(duì)搜索出來(lái)的結(jié)果進(jìn)行過(guò)
濾。
排序
sort
Lucene的搜索結(jié)果默認(rèn)按相關(guān)度排序的。所謂相關(guān)度,就是文檔的得分。Lucene有一個(gè)評(píng)分機(jī)制,就是對(duì)檢索結(jié)果按某種標(biāo)準(zhǔn)進(jìn)行評(píng)估,然后按分值的高低來(lái)對(duì)結(jié)果進(jìn)行排序。
查詢對(duì)象
TermQuery
Term是查詢的最小單位,第一個(gè)參數(shù)是屬性,第
二個(gè)是要查詢的內(nèi)容,下面的代碼的
整個(gè)意思就是在title中查詢檢索
Term term = new
Term(“title”,”檢索”);
Query query = new
TermQuery(term);
關(guān)鍵詞查詢RangeQuery
范圍查詢WildcardQueryPhraseQuery
短語(yǔ)查詢
BooleanQuery
public void
add(Query query, Occur occur)
Occur 用于表示布爾查詢子句關(guān)系的類,包括:
Occur.MUST,Occur.MUST_NOT,Occur.SHOULD。
1,
MUST和MUST:取得連個(gè)查詢子句的交集。
2,
MUST和MUST_NOT:包含MUST并且查詢結(jié)果中不包含MUST_NOT的檢索結(jié)果。
3,
SHOULD與SHOULD,表示“或”關(guān)系,最終檢索結(jié)果為所有檢索子句的并集。
Compass框架
Lucene +
Hibernate
Hibernate操作實(shí)現(xiàn)原理:
主配置文件 :hibernate.cfg.xml
1.連接信息
2.聲明映射文件
3.其他配置
映射文件:.hbm.xml
對(duì)象
– 表
屬性
– 列
同樣,Compass實(shí)現(xiàn)原理如圖:
posted @
2010-01-31 23:35 d66380022|
編輯 收藏
Lucene
今天由湯陽(yáng)光老師(不如說(shuō)是湯兄)給我們講lucene,一見(jiàn)湯兄,太年輕了,真是這感覺(jué)真讓我有些小慚愧,呵呵。。。還是學(xué)好技術(shù)是第一要?jiǎng)?wù)。
從
現(xiàn)在到年前都是湯兄給我們上課,今天和明天是搜索引擎,存儲(chǔ)數(shù)據(jù)用的是Hibernate,全文檢索的簡(jiǎn)化框架是Compass,Lucene講1.5
天,Compass講半天。總結(jié)一天所學(xué)的.全文檢索是目前最流行的技術(shù),由于用數(shù)據(jù)庫(kù)搜索實(shí)現(xiàn)的匹配度,相關(guān)度排序和搜索速度太慢,而這些都非常致命。
下面詳細(xì)回顧:
1.信息檢索:找出與用戶需求相關(guān)的信息
平時(shí)接觸的信息有文:html,doc,pdf和 txt,
多媒體:音頻,視頻,圖片...
全文檢索: 1.只關(guān)注文本。比如我搜索:中國(guó)的首都在哪里?和我搜索中國(guó) 首都
北京是一樣的,我們主要是研究出現(xiàn)了某些詞的文本 2.不處理語(yǔ)義,只是詞匹配
全文檢索的作用:1.bbs,blog,news,商城的站內(nèi)搜索,資源有限
Eclipse的幫助就是用Lucene做的
2.入門(mén)
運(yùn)行原理/入門(mén)概念
Hello World
需求:就像百度的搜索框一樣,輸入內(nèi)容,點(diǎn)擊搜索,得出結(jié)果,并且要求時(shí)間非常短
后臺(tái):點(diǎn)搜索后,會(huì)去信息集合(索引庫(kù))里搜索,注:這個(gè)索引庫(kù)是按照一定的結(jié)構(gòu)存儲(chǔ),這個(gè)結(jié)構(gòu)可以實(shí)現(xiàn)快速搜索
使用流程:1事先就不停再找,建立索引,2.搜索
索引庫(kù)的結(jié)構(gòu):索引庫(kù)是存到一些二進(jìn)制文件,這些文件在同一個(gè)目錄下 --à索引庫(kù)目錄
Document 一條數(shù)據(jù)
Field 數(shù)據(jù)中的一個(gè)字段
Field是組成Document的元素
實(shí)現(xiàn):
步驟:1.建立索引
2.搜索
都用到的是分詞器(analyzer),應(yīng)使用同一種分詞器
實(shí)現(xiàn)HelloWorld:添加jar包
lucene-core-2.4.0.jar(核心);
contrib/analyzers/lucene-analyzers-2.4.0.jar(分詞器);
contrib/highlighter/lucene-highlighter-2.4.0.jar(高亮器);
1.建立Article.java,屬性有id,title,content
2.HelloWorld.java.兩個(gè)主要方法:
1.建立索引:
createIndex()
2.搜索
search()
進(jìn)行搜索
public void search() throws Exception {
String
queryString = "document";
//
1,把要搜索的文本解析為 Query
String[]
fields = { "name", "content" };
QueryParser queryParser = new
MultiFieldQueryParser(fields, analyzer);
Query query
= queryParser.parse(queryString);
//
2,進(jìn)行查詢
IndexSearcher indexSearcher = new IndexSearcher(indexPath);
Filter
filter = null;
TopDocs
topDocs = indexSearcher.search(query, filter, 10000);
System.out.println("總共有【"+topDocs.totalHits+"】條匹配結(jié)果");
// 3,打印結(jié)果
for(ScoreDoc
scoreDoc : topDocs.scoreDocs){
int docSn = scoreDoc.doc; // 文檔內(nèi)部編號(hào)
Document doc = indexSearcher.doc(docSn); // 根據(jù)編號(hào)取出相應(yīng)的文檔
File2DocumentUtils.printDocumentInfo(doc; // 打印出文檔信息
}
}
IndexWriter:操作索引庫(kù),增刪改
主要方法介紹:
// 構(gòu)造方法:如果索引庫(kù)不存在,會(huì)自動(dòng)創(chuàng)建。如果存在,就使用他
new IndexWriter(String/Directory indexPath, Analyzer a,
MaxFieldLength mfl)
// 構(gòu)造方法:第三個(gè)參數(shù)指定是否創(chuàng)建一個(gè)新的索引庫(kù)。
// 1,有索引庫(kù),create為true:會(huì)重新創(chuàng)建。2,沒(méi)有索引庫(kù),create為false,會(huì)報(bào)錯(cuò)。
new IndexWriter(String/Directory indexPath, Analyzer a, boolean
create, MaxFieldLe
ngth mfl)
// 添加索引
addDocument( Document doc )
// 更新
updateDocument(Term term, Document doc)
// 刪除
deleteDocument(Term term)
// 合并索引庫(kù)
addIndexesNoOptimize(Directory[])
今天學(xué)了Lucene的入門(mén),明天學(xué)習(xí)Lucene的高級(jí)知識(shí),以及compass框架!
// 優(yōu)化索引庫(kù)
optimize()
IndexSearcher:操作索引庫(kù),查詢
// 構(gòu)造方法,索引庫(kù)不存在,就報(bào)錯(cuò)
new IndexSearcher( String indexPath )
// 搜索
TopDocs search( Query query, Filter filer, int n )
// 搜索
TopDocs search( Query query, Filter filer, int n , Sort sort)
Document doc( int docSn )
Documet:Lucene所操作的對(duì)象
Field:組成Document的元素,代表一個(gè)屬性。Store、Index
new Field( String name, String value, Store
store, Index index )
Directory:索引庫(kù)(目錄)
FSDirectory
:真實(shí)的目錄