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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jbpm_工作流框架笔记

發布時間:2024/9/27 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jbpm_工作流框架笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.?工作流基礎

1.1.?工作流相關概念

工作流(Workflow),就是“業務過程的部分或整體在計算機應用環境下的自動化”,它主要解決的是“使在多個參與者之間按照某種預定義的規則傳遞文檔、信息或任務的過程自動進行,從而實現某個預期的業務目標,或者促使此目標的實現”。

通俗的說,流程就是多個人在一起合作完成某件事情的步驟,把步驟變成計算機能理解的形式就是工作流

工作流管理系統(WfMSWorkflow?Management?System)的主要功能是通過計算機技術的支持去定義、執行和管理工作流,協調工作流執行過程中工作之間以及群體成員之間的信息交互。工作流需要依靠工作流管理系統來實現。工作流管理系統是定義、創建、執行工作流的系統,應能提供以下三個方面的功能支持:

1.?定義工作流:包括具體的活動、規則等

2.?運行控制功能:在運行環境中管理工作流過程,對工作流過程中的活動進行調度

3.?運行交互功能:指在工作流運行中,WfMS與用戶(活動的參與者)及外部應用程序工具交互的功能。

一、?定義工作流

二、?執行工作流

采用工作流管理系統的優點

1.?提高系統的柔性,適應業務流程的變化?

2.?實現更好的業務過程控制,提高顧客服務質量

3.?降低系統開發和維護成本

工作流框架有:JbpmOSWorkflowActiveBPELYAWL等

OA(辦公自動化)主要技術之一就是工作流。

1.2.?開源工作流jBPM4.4介紹

jBPM?java?Business?Process?Management,是基于java的業務流程管理系統。jBPM是市面上相當流行的一款開源工作流引擎,引擎底層基于Active?Diagram模型。jBPM4.4使用了hibernate3.3.1版),因此可以很好的支持主流數據庫。jBPM4.4共有18張表。

jBPM官方主頁http://www.jboss.org/jbpm

2.?準備jBPM4.4環境

2.1.?jBPM4.4所需環境

jBPM?requires?a?JDK?(standard?java)?version?5?or?higher.?http://java.sun.com/javase/downloads/index.jsp?

To?execute?the?ant?scripts,?you'll?need?apache?ant?version?1.7.0?or?higher:?http://ant.apache.org/bindownload.cgi

2.2.?下載相關資源

1,?jBPM下載地址:http://sourceforge.net/projects/jbpm/files/

2,?Eclipse下載地址(?Eclipse?IDE?for?Java?EE?Developers?(163?MB)Version3.5?):http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo

2.3.?安裝流程設計器(GPDEclipse插件)

GPDGraphical?Process?Designer)是一個Eclipse插件。

安裝方法說明(jBPM4.4User?Guide,?2.11.2.?Install?the?GPD?plugin?into?eclipse):

?Help?-->?Install?New?Software...?

?Click?Add...?

?In?dialog?Add?Site?dialog,?click?Archive...?

?Navigate?to?install/src/gpd/jbpm-gpd-site.zip?and?click?'Open'?

?Clicking?OK?in?the?Add?Site?dialog?will?bring?you?back?to?the?dialog?'Install'?

?Select?the?jPDL?4?GPD?Update?Site?that?has?appeared?

?Click?Next...?and?then?Finish?

?Approve?the?license?

?Restart?eclipse?when?that?is?asked

查看是否成功安裝了插件:WindowàPreference中是否有Jboss?jBPM項。

2.4.?在Eclipse中添加jPDL4.4?Schema校驗

流程定義文件的xsd文件的路徑為:JBPM_HOME/src/jpdl-4.4.xsd

添加到Eclipse中的方法為(jBPM4.4?User?Guide,?2.11.5.?Adding?jPDL?4?schema?to?the?catalog):

?Click?Window?-->?Preferences?

?Select?XML?-->?XML?Catalog?

?Click?'Add...'?

?The?'Add?XML?Catalog?Entry'?dialog?opens?

?Click?the?button?with?the?map-icon?next?to?location?and?select?'File?System...'?

?In?the?dialog?that?opens,?select?file?jpdl-4.4.xsd?in?the?src?directory?of?the?jBPM?installation?root.?

?Click?'Open'?and?close?all?the?dialogs

2.5.?準備jBPM4.4的開發環境

2.5.1.?添加jBPM4.4jar

1.?${JBPM_HOME}/jbpm.jar(核心包)

2.?JBPM_HOME/lib/*.jar,不添加以下jar包:servlet-api.jar,?junit.jar。其中junit.jar一定不要添加,因為是3.8.2版本,與我們使用的junit4有沖突。

3.?所使用的數據庫對應的驅動的jar包(第2步所添加的jar包中已包含mysqljdbc驅動jar包)。

2.5.2.?添加并定制配置文件

1.?配置文件可以從JBPM_HOME/examples/src/中拷貝:
jbpm.cfg.xml
logging.properties
jbpm.hibernate.cfg.xml

2.?修改logging.properties中的日志輸出級別WARNING:?java.util.logging.ConsoleHandler.level=WARNING

3.?修改jbpm.hibernate.cfg.xml中的數據庫連接信息。如果使用MySql,使用的方言一定要是org.hibernate.dialect.MySQL5InnoDBDialect。

4.?數據庫連接編碼一定要是UTF-8。否則可能會在部署含有中文字符的流程定義時會拋異常,說sql語法錯誤。

說明:如果要改變jbpm.hibernate.cfg.xml的文件名稱,需要做:

1、從JBPM_HOME/src/中拷貝jbpm.tx.hibernate.cfg.xml放到工程的src/下,然后進行修改。

2、修改jbpm.tx.hibernate.cfg.xml中的hibernate主配置文件的路徑配置(指定的是相對于classpath的相對路徑)。

2.5.3.?初始化數據庫

1,?方法一:執行sql腳本文件${JBPM4.4_HOME}/install/src/db/create/jbpm.*.create.sql

2,?方法二:使用Hibernate的自動建表,在jbpm.hibernate.cfg.xml中配置:hibernate.hbm2ddl.auto=update

3.?核心概念與相關API(Service?API)

3.1.?概念:Process?definition,?process?instance?,??execution

3.1.1.?Process?definition

ProcessDefinition,流程定義:

一個流程的步驟說明。如一個請假流程、報銷流程、借款流程等,是一個規則。

例:

3.1.2.?Process?instance

ProcessInstance,流程實例:

代表流程定義的一次執行。如張三昨天按請假流程請了一次假。一個流程實例包括了所有運行階段,?其中最典型的屬性就是跟蹤當前節點的指針。

3.1.3.?Execution

Execution,執行:

一般情況下,一個流程實例是一個執行樹的根節點。?

使用樹狀結構的原因在于,?這一概念只有一條執行路徑,?使用起來更簡單。?業務API不需要了解流程實例和執行之間功能的區別。?因此,?API里只有一個執行類型來引用流程實例和執行。

假設匯款和存檔可以同時執行,那么主流程實例就包含了2個用來跟蹤狀態的子節點:

4.1.?ProcessEngineService?API

4.1.1.?ConfigurationProcessEngine

Interacting?with?jBPM?occurs?through?services.?The?service?interfaces?can?be?obtained?from?the?ProcessEngine?which?is?build?from?a?Configuration.?A?ProcessEngine?is?thread?safe?and?can?be?stored?in?a?static?member?field.

使用默認的配置文件(jbpm.cfg.xml生成Configuration并構建ProcessEngine

ProcessEngine?processEngine?=?new?Configuration()

.buildProcessEngine();

或是使用如下代碼獲取使用默認配置文件的、單例的ProcessEngine對象:

ProcessEngine?processEngine?=?Configuration.getProcessEngine();

或是使用指定的配置文件(要放到classPath):

ProcessEngine?processEngine?=?new?Configuration()

??????.setResource("my-own-configuration-file.xml")

??????.buildProcessEngine();

4.1.2.?jBPM?Service?API

jBPM所有的操作都是通過Service完成的,以下是獲取Service的方式:

RepositoryService?repositoryService?=?processEngine

.getRepositoryService();

ExecutionService?executionService?=?processEngine

.getExecutionService();

TaskService?taskService?=?processEngine

.getTaskService();

HistoryService?historyService?=?processEngine

.getHistoryService();

ManagementService?managementService?=?processEngine

.getManagementService();

各個Service的作用:

RepositoryService

管理流程定義

ExecutionService

管理執行的,包括啟動、推進、刪除Execution等操作

TaskService

管理任務的

HistoryService

歷史管理(執行完的數據管理,主要是查詢

IdentityService

jBPM的用戶、組管理

ManagementService

4.1.3.?API風格

方法調用鏈

每一個方法都是流程有關的一個業務操作,默認是一個獨立的事務。

4.1.4.?查詢的有關API(風格)

功能說明

相應的查詢API

查詢“流程定義”

ProcessDefinitionQuery?processDefinitionQuery?=?

processEngine.getRepositoryService()

.createProcessDefinitionQuery();

查詢“執行對象”

(流程實例)

ProcessInstanceQuery?processInstanceQuery?=?

processEngine.getExecutionService()?//

.createProcessInstanceQuery();

查詢“任務”

TaskQuery?taskQuery?=?//

processEngine.getTaskService()//

.createTaskQuery();

查詢“執行歷史”

(流程實例歷史)

HistoryProcessInstanceQuery?historyProcessInstanceQuery?=?

processEngine.getHistoryService()

.createHistoryProcessInstanceQuery();

查詢“任務歷史”

HistoryTaskQuery?historyTaskQuery?=?

processEngine.getHistoryService()

.createHistoryTaskQuery();

以上列出的Query對象有:

1.?ProcessDefinitionQuery

2.?ProcessInstanceQuery

3.?TaskQuery

4.?HistoryProcessInstanceQuery

5.?HistoryTaskQuery

這些Query對象的使用方法都是一致的,如下所示:

1,?添加過濾條件:調用其中的有關方法指定條件即可。如:

a)?processDefinitionQuery.processDefinitionKey("請假")是指定查詢key請假的流程定義;

b)?taskQuery.assignee("張三")是指定辦理人為張三的任務。

2,?添加排序條件:

a)?調用?xxQuery.orderAsc(property),表示按某屬性升序排列

b)?調用?xxQuery.orderDesc(property),表示按某屬性降序排列

c)?可指定多個排序條件,就是代表第1順序,第2順序…等。

d)?屬性名在各自的Query對象(接口)中有常量定義,如:

i.?ProcessDefinitionQuery.PROPERTY_ID

ii.?ProcessDefinitionQuery.PROPERTY_KEY

iii.?TaskQuery.PROPERTY_NAME

iv.?TaskQuery.PROPERTY_ASSIGNEE

3,?指定分頁有關信息:

a)?調用方法xxQuery.page(firstResult,?maxResults);

b)?這是指定firstmax的值(就是Hibernate中的Query.setFirstResult()Query.setMaxResults()

c)?如果沒有調用這個方法,代表要查詢出符合條件的所有記錄。

4,?查詢得到結果:

a)?調用方法xxQuery.list();?表示查詢列表

b)?調用方法?xxQuery.uniqueResult();?表示查詢唯一的結果

c)?調用方法xxQuery.count();?表示查詢符合條件的記錄數量

5.?管理流程定義

沒有更新功能

5.1.?部署流程定義

注意區分Deployment與ProcessDefinition

5.1.1.?示例代碼1:流程定義有關文件在classpath

String?deploymentId?=?processEngine.getRepositoryService()

.createDeployment()

.addResourceFromClasspath("process/test.jpdl.xml")

.addResourceFromClasspath("process/test.png")

.deploy();

5.1.2.?示例代碼2:一次添加多個流程定義有關文件(要先打成zip包)

String?deploymentId?=?processEngine.getRepositoryService()

.createDeployment()

.addResourcesFromZipInputStream(zipInputStream)

.deploy();

5.1.3.?說明

1,?.addResourceFromClasspath(resource);?可以調用多次以添加多個文件。文件重復添加也不會報錯。

2,?.addResourceFromInputStream(resourceName,?inputStream)添加一個文件(使用InputStream

3,?.addResourcesFromZipInputStream(zipInputStream)添加多個文件,里面也可以有文件夾。

4,?以上方法可以在一起調用。

5.2.?刪除流程定義

5.2.1.?示例代碼1:刪除流程定義,如果有關聯的流程實例信息則報錯

repositoryService.deleteDeployment(deploymentId);

5.2.2.?示例代碼2:刪除流程定義,并刪除關聯的流程實例與歷史信息

repositoryService.deleteDeploymentCascade(deploymentId);

5.3.?查詢流程定義

5.3.1.?相關查詢API說明:ProcessDefinitionQuery

RepositoryService.createProcessDefinitionQuery()

5.3.2.?示例代碼1:查詢所有流程定義

//?1,構建查詢

ProcessDefinitionQuery?pdQuery?=?processEngine.getRepositoryService()?

.createProcessDefinitionQuery()//?

.orderAsc(ProcessDefinitionQuery.PROPERTY_NAME)//

.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION);

//?2,查詢出總數量與數據列表

long?count?=?pdQuery.count();

List<ProcessDefinition>?list?=?pdQuery.page(0,?100).list();//?分頁:取出前100條記錄

//?3,顯示結果

System.out.println(count);

for?(ProcessDefinition?pd?:?list)?{

System.out.println("id="?+?pd.getId()//

+?",deploymentId="?+?pd.getDeploymentId()//

+?",name="?+?pd.getName()//

+?",version="?+?pd.getVersion()//

+?",key="?+?pd.getKey());?//

}

5.3.3.?示例代碼2:查詢所有最新版本的流程定義列表

//?1,查詢version升序排序,則最大版本排在最后

List<ProcessDefinition>?all?=?processEngine.getRepositoryService()//

.createProcessDefinitionQuery()//

.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)

.list();

//?2,過濾出所有不同Key的最新版本(因為最大版本在最后面)

Map<String,?ProcessDefinition>?map?=?new?HashMap<String,?ProcessDefinition>();?//?mapkey是流程定義的keymapvlaue是流程定義對象

for?(ProcessDefinition?pd?:?all)?{

map.put(pd.getKey(),?pd);

}

Collection<ProcessDefinition>?result?=?map.values();

//?3,顯示結果

for?(ProcessDefinition?pd?:?result)?{

System.out.println("deploymentId="?+?pd.getDeploymentId()//?

+?",\t?id="?+?pd.getId()//?流程定義的id,格式:{key}-{version}

+?",\t?name="?+?pd.getName()

+?",\t?key="?+?pd.getKey()

+?",\t?version="?+?pd.getVersion());

}

5.4.?獲取部署對象中的文件資源內容

//?資源的名稱,就是?jbpm4_lob?表中的?NAME_?列表值

String?deploymentId?=?"90001";

String?resourceName?=?"test.png";?

InputStream?in?=?processEngine.getRepositoryService()

.getResourceAsStream(deploymentId,?resourceName);

5.5.?獲取流程圖中某活動的坐標

String?processDefinitionId?=?"test-1";?//?流程定義的id

String?activityName?=?"start1";?//?活動的名稱

ActivityCoordinates?c?=?processEngine.getRepositoryService()

.getActivityCoordinates(processDefinitionId,?activityName);

System.out.println("x="?+?c.getX()?

+?",y="?+?c.getY()?

+?",width="?+?c.getWidth()?

+?",height="?+?c.getHeight());

6.?執行流程實例

6.1.?啟動流程實例

說明:流程實例創建后,直接就到開始活動后的第一個活動,不會在開始活動停留。

6.1.1.?示例代碼1:使用指定key的最新版本的流程定義啟動流程實例

ProcessInstance?pi?=?processEngine.getExecutionService()

.startProcessInstanceByKey(processDefinitionKey);

6.1.2.?示例代碼2:使用指定key的最新版本的流程定義啟動流程實例,并設置一些流程變量

//?準備流程變量

Map<String,?Object>?variables?=?new?HashMap<String,?Object>();

variables.put("申請人",?"張三");

variables.put("報銷金額",?1000.00);

//?啟動流程實例,并設置一些流程變量

ProcessInstance?pi?=?processEngine.getExecutionService()

.startProcessInstanceByKey(processDefinitionKey,?variables);

6.2.?向后執行一步(Signal

6.2.1.?示例代碼1:向后執行一步,使用唯一的outcome離開活動

processEngine.getExecutionService().signalExecutionById(executionId);

6.2.2.?示例代碼2:向后執行一步,使用唯一的outcome離開活動,并設置一些流程變量

Map<String,?Object>?variables?=?new?HashMap<String,?Object>();

variables.put("審批結果",?"同意");

processEngine.getExecutionService()

.signalExecutionById(executionId,?variables);

6.2.3.?示例代碼3:向后執行一步,使用指定的outcome離開活動

String?outcome=?"to?end1";

processEngine.getExecutionService()

.signalExecutionById(executionId,?outcome);

6.2.4.?示例代碼4:向后執行一步,使用指定的outcome離開活動,并設置一些流程變量

String?outcome=?"to?end1";

Map<String,?Object>?variables?=?new?HashMap<String,?Object>();

variables.put("審批結果",?"同意");

processEngine.getExecutionService()

.signalExecutionById(executionId,?outcome,?variables);

6.3.?查詢任務

6.3.1.?查詢個人任務列表

方式1TaskService.findPersonalTasks(userId);

方式2List<Task>?list?=?taskService.createTaskQuery()

.assignee(userId)

.list();

//?顯示任務信息

for?(Task?task?:?taskList)?{

System.out.println("id="?+?task.getId()//?任務的id

+?",name="?+?task.getName()//?任務的名稱

+?",assignee="?+?task.getAssignee()//?任務的辦理人

+?",createTime="?+?task.getCreateTime()?//?任務的創建(生成)的時間

+?",executionId="?+?task.getExecutionId());//?任務所屬流程實例的id

}

6.3.2.?查詢組任務列表

方式1?taskService.findGroupTasks(userId);

方式2?List<Task>?list?=?processEngine.getTaskService()//

.createTaskQuery()//

.candidate(userId)//

.list();

6.4.?完成任務

6.4.1.?正常完成任務(也可以同時設置一些流程變量)

String?taskId?=?"420001";

processEngine.getTaskService().completeTask(taskId);

processEngine.getTaskService().completeTask(taskId,?outcome);

processEngine.getTaskService().completeTask(taskId,?outcome,?variables);

6.4.2.?自行控制任務完成后是否可向后流轉

String?taskId?=?"420001";

//?1設置為false代表:辦理完任務后不向后移動(默認為true

TaskImpl?taskImpl?=?(TaskImpl)?processEngine

.getTaskService().getTask(taskId);

taskImpl.setSignalling(false);?

//?2,辦理完任務

processEngine.getTaskService().completeTask(taskId);

6.5.?拾取任務

1,?TaskService.takeTask(taskId,?userId),拾取組任務到個人任務列表中,如果任務有assignee,則會拋異常。

2,?processEngine.getTaskService().assignTask(taskId,?userId),轉交任務給其他人,(如果任務有assignee,則執行這個方法代表重新分配。也可以把assignee設為null表示組任務沒有人辦理了)

6.6.?設置與獲取流程變量

6.6.1.?設置流程變量

6.6.1.1.?方式1:根據?executionId?設置或獲取流程變量

ExecutionService.setVariable(executionId,?name,?value);

Object?obj?=?executionService.getVariable(executionId,?"請假人");

6.6.1.2.?方式2:根據?taskId?設置或獲取流程變量

TaskService.setVariables(taskId,?variables);?//?一次設置多個變量

Object?obj?=?executionService.getVariable(executionId,?"請假人");

6.6.1.3.?流程變量所支持的值的類型(jBPM?User?Guide,7.2.?Variable?types)

7.2.?Variable?types

jBPM?supports?following?Java?types?as?process?variables:

?java.lang.String?

?java.lang.Long?

?java.lang.Double?

?java.util.Date?

?java.lang.Boolean?

?java.lang.Character?

?java.lang.Byte?

?java.lang.Short?

?java.lang.Integer?

?java.lang.Float?

?byte[]?(byte?array)?

?char[]?(char?array)?

?hibernate?entity?with?a?long?id?

?hibernate?entity?with?a?string?id?

?serializable

For?persistence?of?these?variable,?the?type?of?the?variable?is?checked?in?the?order?of?this?list.?The?first?match?will?determine?how?the?variable?is?stored.?

6.7.?直接結束流程實例(自己手工結束)

String?processInstanceId?=?"test.10001";

processEngine.getExecutionService()

.endProcessInstance(processInstanceId,?ProcessInstance.STATE_ENDED);

7.?jBPM4.4的流程定義語言(設計流程)

7.1.?process(流程)

.jpdl.xml的根元素,可以指定的屬性有:

屬性名

作用說明

name

流程定義的名稱,用于顯示。

key

流程定義的key,用于查詢。

如未指定,則默認為name的值。

version

版本,如果指定,則不能與已有的流程定義的版本重復;如未指定,則此key的流程定義的第1個為版本1,以后的是版本遞增(每次加1

7.2.?transition(連線、轉移)

1,?一個活動中可以指定一個或多個TransitionStart中只能有一個,End中沒有)。

a)?開始活動中只能有一個Transition

b)?結束活動中沒有Transition

c)?其他活動中有1條或多條Transition

2,?如果只有一個,則可以不指定名稱(名稱是null);如果有多個,則要分別指定唯一的名稱。

7.3.?流轉控制活動

7.3.1.?start(開始活動)

代表流程的開始邊界,一個流程有且只能有一個Start活動。開始活動只能指定一個Transition。在流程實例啟動后,會自動的使用這個唯一的Transition離開開始活動,到一下個活動。

7.3.2.?endend-errorend-cancel(結束活動)

代表流程的結束邊界,可以有多個,也可以沒有。如果有多個,則到達任一個結束活動,整個流程就都結束了;如果沒有,則到達最后那個沒有Transition的活動,流程就結束了。

7.3.3.?state(狀態活動)

功能:等待。

7.3.4.?task(任務活動)

分配任務:

1,?actor=#{String型的變量}

2,?AssignmentHandler,需要在<task>元素中寫<assignment-handler?class="AssignmentHandlerImpl"/>子元素。

a)?指定的類要實現AssignmentHandler接口

b)?在其中可以使用Assignable.setAssignee(String),分配個人任務。

7.3.5.?decision(判斷活動)

1,使用expression,如:expr="#{'to?state2'}"

2,使用Handler,要實現DecisionHandler接口

3,如果同時配置了expressionHandler,則expression有效,忽略Handler

7.3.6.?forkjoin(分支/聚合活動)

這是多個分支并行(同時)執行的,并且所有的分支Execution都到Join活動后才離向后執行。

7.4.?自定義活動(Custom

1,在<custom>元素中指定class屬性為指定的類。

2,這個類要實現ExternalActivityBehaviour接口,其中有兩個方法:

1execute(ActivityExecution),節點的功能代碼

2signal(ActivityExecution,?String,?Map),在當前節點等待時,外部發信號時的行為

3,在execute()方法中,可以調用以下方法對流程進行控制

1ActivityExecution.waitForSignal(),在當前節點等待。

2ActivityExecution.takeDefaultTransition(),使用默認的Transition離開,當前節點中定義的第一個為默認的。

3ActivityExecution.take(String?transitionName),使用指定的Transition離開

4ActivityExecution.end(),結束流程實例

4,也可以實現ActivityBehaviour接口,只有一個方法execute(ActivityExecution),這樣就不能等待,否則signal時會有類轉換異常。

7.5.?事件

1,?在根元素中,或在節點元素中,使用<on?event="">元素指定事件,其中event屬性代表事件的類型。

2,?在<on>中用子元素<event-listener?class="EventListenerImpl"?/>,指定處理的類,要求指定的類要實現EventListener接口

3,? 事件類型:

a)?<on>元素放在根元素(<process>)中,可以指定eventstartend,表示流程的開始與結束。

b)?<on>元素放在節點元素中,可以指定eventstartend,表示節點的進入與離開

c)?在Start節點中只有end事件,在End節點中只有start事件。

d)?在<transition>元素中直接寫<event-listener?class="">,就是配置事件。(因為在這里只有一個事件,所以不用寫on與類型)

e)?在<task>元素中還可以配置assign事件,是在分配任務時觸發的。

8.?jBPM4.4應用

8.1.?與Spring集成(jBPM4.4?Developers?Guide,?Chapter?17.?Spring?Integration

8.1.1.?在jbpm.cfg.xml

1,刪除配置:<import?resource="jbpm.tx.hibernate.cfg.xml"?/>

2,增加配置:<import?resource="jbpm.tx.spring.cfg.xml"?/>

8.1.2.?在applicationContext.xml中配置

<!--?配置ProcessEngine(整合jBPM4)?-->

<!--?jbpmCfg是相對于classpath的相對路徑,默認值為jbpm.cfg.xml?-->

<bean?id="springHelper"?

class="org.jbpm.pvm.internal.processengine.SpringHelper">

<property?name="jbpmCfg"?value="jbpm.cfg.xml"></property>

</bean>

<bean?id="processEngine"?factory-bean="springHelper"?

factory-method="createProcessEngine"?/>

8.1.3.?測試

@Test?//?測試ProcessEngine

public?void?testProcessEngine()?{

ProcessEngine?processEngine?=?(ProcessEngine)ac.getBean("processEngine");

Assert.assertNotNull(processEngine);

}

8.1.4.?注意事項

如果做了JBPM4.4Spring整合(使用了jbpm.tx.spring.cfg.xml),則在程序中就一定要使用Spring注入ProcessEngine,千萬不能使用Configuration.getProcessEngine()生成ProcessEngine,因為這時內部的代碼有以下邏輯:如果整合了Spring但沒有ApplicationContext,就默認讀取applicationContext.xml創建ApplicationContext實例并從中獲取名為”ProcessEngine”的對象。而這時如果把pe?=?Configuration.getProcessEngine()寫成某Spring中管理的bean的初始化代碼,就會有無限循環,不停的創建ApplicationContext了!

8.2.?自行控制事務

1,?修改?jbpm.tx.hibernate.cfg.xml

a)?不讓jBPM自行管理事務:去掉<standard-transaction-interceptor?/>

b)?讓Jbpm使用SessionFactory.getCurrentSession():修改為?<hibernate-session?current="true"?/>

2,?配置可以使用SessionFactory.getCurrentSession(),在jbpm.hibernate.cfg.xml?中配置:<property?name="hibernate.current_session_context_class">thread</property>

3,?要使用同一個SessionFactory,且都要使用?SessionFactory.getCurrentSession()?獲取?Session

a)?同一個SessionFactorySessionFactory?sf?=?processEngine.get(SessionFactory.class)

b)?在?BaseDaoImpl?中增加:

i.?getSession()?{?return?HibernateUtils.getSessionFactory().getCurrentSession();?}

ii.?getProcessEngine(){?return?org.jbpm.api.Configuration.getProcessEngine();?}

4,?統一的打開與提交或回滾事務:使用?OpenSessionInViewFilter?控制事務。

8.3.?啟動Tomcat后,訪問JSP時(使用的是MyEclipse自帶的Tomcat,是6.0的版本),報錯:???Caused?by:?java.lang.LinkageError:?loader?constraints?violated?when?linking?javax/el/ExpressionFactory?class

at?org.apache.jsp.WEB_002dINF.jsp.UserAction.loginUI_jsp._jspInit(loginUI_jsp.java:39)

at?org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)

at?org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)

at?org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)

at?org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)

at?org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)

...?40?more

說明:原因是Jbpmjuel.jar,?juel-engine.jar,?juel-impl.jar包和Tomcat6.0中的el-api.jar包沖突了。

有三個解決辦法:

1,方法一:在MyEclipsePreferences?->?MyEclipse?->?Application?Servers?->?Tomcat?->?..?->?Paths?中配置?Append?to?classpath,選中?juel.jar,?juel-engine.jar,?juel-impl.jar?這三個jar包就可以了。

2,方法二:將?juel.jar,?juel-engine.jar,?juel-impl.jar?這三個包復制到tomcat6下?lib/?中,并刪除原來的el-api.jar

切記還要把工程中?WEB-INF\lib?下的?juel.jar,?juel-engine.jar,?juel-impl.jar?刪除,不然還是要沖突。

3,方法三:換成tomcat5.5,就沒有問題了。

8.4.?完成流程實例中的最后一個任務時報錯(任務實例結束時),或刪除流程定義級聯刪除流程實例時,報錯如下:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException:?Cannot?delete?or?update?a?parent?row:?a?foreign?key?constraint?fails?(`itcastoa_20100909/jbpm4_execution`,?CONSTRAINT?`FK_EXEC_INSTANCE`?FOREIGN?KEY?(`INSTANCE_`)?REFERENCES?`jbpm4_execution`?(`DBID_`))

解決辦法:把方言設為?MySQL5InnoDBDialect,不能是?MySQLDialect

總結

以上是生活随笔為你收集整理的jbpm_工作流框架笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。