工作流(workflow)就是工作流程的計(jì)算模型,即將工作流程中的工作如何前后組織在一起的邏輯和規(guī)則在計(jì)算機(jī)中以恰當(dāng)?shù)哪P瓦M(jìn)行表示并對(duì)其實(shí)施計(jì)算。它主要解決的是“使在多個(gè)參與者之間按照某種預(yù)定義的規(guī)則傳遞文檔、信息或任務(wù)的過(guò)程自動(dòng)進(jìn)行,從而實(shí)現(xiàn)某個(gè)預(yù)期的業(yè)務(wù)目標(biāo),或者促使此目標(biāo)的實(shí)現(xiàn)”。(我的理解就是:將部分或者全部的工作流程、邏輯讓計(jì)算機(jī)幫你來(lái)處理,實(shí)現(xiàn)自動(dòng)化)
所謂工作流引擎是指workflow作為應(yīng)用系統(tǒng)的一部分,并為之提供對(duì)各應(yīng)用系統(tǒng)有決定作用的根據(jù)角色、分工和條件的不同決定信息傳遞路由、內(nèi)容等級(jí)等核心解決方案。
例如開(kāi)發(fā)一個(gè)系統(tǒng)最關(guān)鍵的部分不是系統(tǒng)的界面,也不是和數(shù)據(jù)庫(kù)之間的信息交換,而是如何根據(jù)業(yè)務(wù)邏輯開(kāi)發(fā)出符合實(shí)際需要的程序邏輯并確保其穩(wěn)定性、易維護(hù)性和彈性。
比如你的系統(tǒng)中有一個(gè)任務(wù)流程,一般情況下這個(gè)任務(wù)的代碼邏輯、流程你都要自己來(lái)編寫(xiě)。實(shí)現(xiàn)它是沒(méi)有問(wèn)題的。但是誰(shuí)能保證邏輯編寫(xiě)的毫無(wú)紕漏?經(jīng)過(guò)無(wú)數(shù)次的測(cè)試與改進(jìn),這個(gè)流程沒(méi)有任何漏洞也是可以實(shí)現(xiàn)的,但是明顯就會(huì)拖慢整個(gè)項(xiàng)目的進(jìn)度。
工作流引擎解決的就是這個(gè)問(wèn)題:如果應(yīng)用程序缺乏強(qiáng)大的邏輯層,勢(shì)必變得容易出錯(cuò)(信息的路由錯(cuò)誤、死循環(huán)等等)。
BPMN(Business PRocess Model and Notation)--業(yè)務(wù)流程模型與符號(hào)。
BPMN是一套流程建模的標(biāo)準(zhǔn),主要目標(biāo)是被所有業(yè)務(wù)用戶(hù)容易理解的符號(hào),支持從創(chuàng)建流程輪廓的業(yè)務(wù)分析到這些流程的最終實(shí)現(xiàn),知道最終用戶(hù)的管理監(jiān)控。
通俗一點(diǎn)其實(shí)就是一套規(guī)范,畫(huà)流程模型的規(guī)范。流程模型包括:流程圖、協(xié)作圖、編排圖、會(huì)話(huà)圖。詳細(xì)信息請(qǐng)google。
學(xué)習(xí)過(guò)Activiti的朋友都知道,Activiti的創(chuàng)始人也就是JBPM(也是一個(gè)優(yōu)秀的BPM引擎)的創(chuàng)始人,從Jboss離職后開(kāi)發(fā)了一個(gè)新的BPM引擎:Activiti。所以,Activiti有很多地方都有JBPM的影子。所以,據(jù)說(shuō)學(xué)習(xí)過(guò)JBPM的朋友學(xué)起Activiti來(lái)非常順手。
由于本人之前沒(méi)有工作流及JBPM的相關(guān)基礎(chǔ),剛開(kāi)始學(xué)習(xí)Activiti的時(shí)候可以說(shuō)是無(wú)比痛苦的,根本不知道從何下手,這里也建議大家先進(jìn)行工作流及BPMN2.0規(guī)范的學(xué)習(xí),有了一定的基礎(chǔ)后,再著手學(xué)習(xí)Activiti。
Activiti是一個(gè)開(kāi)源的工作流引擎,它實(shí)現(xiàn)了BPMN 2.0規(guī)范,可以發(fā)布設(shè)計(jì)好的流程定義,并通過(guò)api進(jìn)行流程調(diào)度。
Activiti 作為一個(gè)遵從 Apache 許可的工作流和業(yè)務(wù)流程管理開(kāi)源平臺(tái),其核心是基于 java 的超快速、超穩(wěn)定的 BPMN2.0 流程引擎,強(qiáng)調(diào)流程服務(wù)的可嵌入性和可擴(kuò)展性,同時(shí)更加強(qiáng)調(diào)面向業(yè)務(wù)人員。
Activiti 流程引擎重點(diǎn)關(guān)注在系統(tǒng)開(kāi)發(fā)的易用性和輕量性上。每一項(xiàng) BPM 業(yè)務(wù)功能 Activiti 流程引擎都以服務(wù)的形式提供給開(kāi)發(fā)人員。通過(guò)使用這些服務(wù),開(kāi)發(fā)人員能夠構(gòu)建出功能豐富、輕便且高效的 BPM 應(yīng)用程序。
以上部分對(duì)工作流、BPMN、Activiti的概念做了一個(gè)簡(jiǎn)單的介紹,目的是了解Activiti究竟是什么,能做些什么…及在學(xué)習(xí)Activiti之前需要了解的知識(shí)與技術(shù)。其中大部分文字來(lái)自Copy網(wǎng)上的各種資料與文檔,通過(guò)總結(jié)而來(lái)的。具體的更詳細(xì)的內(nèi)容需自己google,參考一些官方的文檔與手冊(cè)。
本文檔之后內(nèi)容如下:
1) 下載與使用
2) 核心組件與說(shuō)明
3) 入門(mén)示例
4) Eclipse中的Activiti插件的使用
本文檔旨在為初學(xué)Activiti的朋友提供入門(mén)級(jí)別的參考,不會(huì)對(duì)其原理及其結(jié)構(gòu)進(jìn)行深層次的探究(更多是因?yàn)槟壳白陨砝斫膺€不是很透徹),只是為大家理清思路,方便以后更深層次的學(xué)習(xí)。本文檔還有一個(gè)重要的特點(diǎn),那就是根據(jù)自己看官方手冊(cè)的經(jīng)驗(yàn),教大家如何看手冊(cè)從而更有效率!由于是初學(xué),很多術(shù)語(yǔ)或解釋難免理解有偏差,所以一定要看官方提供的文檔與手冊(cè),那才是學(xué)習(xí)的最佳途徑!
下載Activiti:下載路徑,也就是官方網(wǎng)站的地址:http://activiti.org/download.html。下載后解壓(我所使用的是5.12版本的,Activiti更新速度飛快,幾乎每?jī)蓚€(gè)月就會(huì)有一個(gè)更新的小版本),看到如下目錄:
1) database:里面存放的是Activiti使用到的數(shù)據(jù)庫(kù)信息的sql文件,它支持的數(shù)據(jù)庫(kù)類(lèi)型如下圖,使用時(shí)只需執(zhí)行你自己的數(shù)據(jù)庫(kù)類(lèi)型的文件即可。如:你的數(shù)據(jù)庫(kù)是MySQL,那么就執(zhí)行activiti.mysql.create.*.sql即可。
2) docs:毫無(wú)疑問(wèn),api文檔是也。
3) libs:使用Activiti所需要的所有的jar包和源文件。
4) wars:官方給我們提供的示例Demo,通過(guò)使用Demo可以更加快速的了解Activiti。
使用Activiti,首先當(dāng)然要有jdk了!6+版本就可以了。其次,要有一款I(lǐng)DE,我們當(dāng)然會(huì)使用Eclipse,這里使用Juno版本。然后,web容器當(dāng)然也要有,這里使用Tomcat6.0版本。然后就是Activiti的Eclipse插件了,這個(gè)后面再介紹。
所謂的一分鐘入門(mén)就是通過(guò)運(yùn)行你下載的包里的wars文件夾里的activiti-explorer.war文件,以便更快的了解Activiti。將文件拷貝至Tomcat的webapps目錄,啟動(dòng)tomcat,輸入http://localhost:8080/activiti-explorer。然后你就可以開(kāi)整了!總算是有一點(diǎn)微小的進(jìn)展了。
這里需要說(shuō)明的就是,這個(gè)Demo默認(rèn)采用的是h2內(nèi)存數(shù)據(jù)庫(kù),如果想用你自己的數(shù)據(jù)庫(kù),就需要修改web應(yīng)用WEB-INF/classes目錄下的db.properties。然后,按上面說(shuō)的,把database里的create文件夾里的數(shù)據(jù)庫(kù)文件導(dǎo)入你自己的數(shù)據(jù)庫(kù)(如果沒(méi)有修改db.properties,就不用導(dǎo)入了)。
Demo的具體解釋與數(shù)據(jù)庫(kù)配置的具體信息詳見(jiàn)官方手冊(cè),手冊(cè)已經(jīng)說(shuō)的很清楚了。這里需要重點(diǎn)了解activiti.cfg.xml的配置以及如何構(gòu)建ProcessEngine(配置文件構(gòu)建方式、代碼構(gòu)建方式)。
對(duì)Demo的使用介紹在官方文檔的后面才開(kāi)始介紹,這里建議應(yīng)用跑起來(lái)之后,先自己試試手(可看后面介紹Demo如何使用的章節(jié)),看看如何跑一個(gè)流程、整個(gè)流程是怎么流的、并隨時(shí)關(guān)注數(shù)據(jù)庫(kù)表里的數(shù)據(jù)的變化等,對(duì)以后的學(xué)習(xí)很有幫助!
1. Deployment:流程部署對(duì)象,部署一個(gè)流程時(shí)創(chuàng)建。
2. ProcessDefinitions:流程定義,部署成功后自動(dòng)創(chuàng)建。
3. ProcessInstances:流程實(shí)例,啟動(dòng)流程時(shí)創(chuàng)建。
4. Task:任務(wù),在Activiti中的Task僅指有角色參與的任務(wù),即定義中的UserTask。
5. Execution:執(zhí)行計(jì)劃,流程實(shí)例和流程執(zhí)行中的所有節(jié)點(diǎn)都是Execution,如UserTask、ServiceTask等。
1. ProcessEngine:流程引擎的抽象,通過(guò)它我們可以獲得我們需要的一切服務(wù)。
2. RepositoryService:Activiti中每一個(gè)不同版本的業(yè)務(wù)流程的定義都需要使用一些定義文件,部署文件和支持?jǐn)?shù)據(jù)(例如BPMN2.0 XML文件,表單定義文件,流程定義圖像文件等),這些文件都存儲(chǔ)在Activiti內(nèi)建的Repository中。RepositoryService提供了對(duì) repository的存取服務(wù)。
3. RuntimeService:在Activiti中,每當(dāng)一個(gè)流程定義被啟動(dòng)一次之后,都會(huì)生成一個(gè)相應(yīng)的流程對(duì)象實(shí)例。RuntimeService提供了啟動(dòng)流程、查詢(xún)流程實(shí)例、設(shè)置獲取流程實(shí)例變量等功能。此外它還提供了對(duì)流程部署,流程定義和流程實(shí)例的存取服務(wù)。
4. TaskService: 在Activiti中業(yè)務(wù)流程定義中的每一個(gè)執(zhí)行節(jié)點(diǎn)被稱(chēng)為一個(gè)Task,對(duì)流程中的數(shù)據(jù)存取,狀態(tài)變更等操作均需要在Task中完成。TaskService提供了對(duì)用戶(hù)Task 和Form相關(guān)的操作。它提供了運(yùn)行時(shí)任務(wù)查詢(xún)、領(lǐng)取、完成、刪除以及變量設(shè)置等功能。
5. IdentityService: Activiti中內(nèi)置了用戶(hù)以及組管理的功能,必須使用這些用戶(hù)和組的信息才能獲取到相應(yīng)的Task。IdentityService提供了對(duì)Activiti 系統(tǒng)中的用戶(hù)和組的管理功能。
6. ManagementService: ManagementService提供了對(duì)Activiti流程引擎的管理和維護(hù)功能,這些功能不在工作流驅(qū)動(dòng)的應(yīng)用程序中使用,主要用于Activiti系統(tǒng)的日常維護(hù)。
7. HistoryService: HistoryService用于獲取正在運(yùn)行或已經(jīng)完成的流程實(shí)例的信息,與RuntimeService中獲取的流程信息不同,歷史信息包含已經(jīng)持久化存儲(chǔ)的永久信息,并已經(jīng)被針對(duì)查詢(xún)優(yōu)化。
現(xiàn)在至少要知道有這些對(duì)象和接口。并結(jié)合Activiti Api這一章節(jié)來(lái)看,你就會(huì)對(duì)部署流程、啟動(dòng)流程、執(zhí)行任務(wù)等操作有一個(gè)基本的概念。之后編寫(xiě)一個(gè)簡(jiǎn)單的單元測(cè)試,主要為了測(cè)試activiti.cfg.xml配置的是否正確,流程是否可以被部署即可。
至于與spring的集成,一定要熟悉基于Spring配置Activiti,以及事務(wù)的處理。
下面開(kāi)始編寫(xiě)一個(gè)示例。這個(gè)Demo為一個(gè)“月度報(bào)表申請(qǐng)”流程。由“sales(銷(xiāo)售)”組的用戶(hù)制作月度報(bào)表,提交給“management(經(jīng)理)”組的用戶(hù),經(jīng)理審批該報(bào)表,最后結(jié)束。流程圖如下:
這個(gè)Demo完成之后,我們會(huì)進(jìn)行兩個(gè)測(cè)試。一個(gè)是代碼中的單元測(cè)試,就是跑一遍流程,看一下流程在跑的過(guò)程中輸出的信息;一個(gè)是我們將編輯好的bpmn20.xml文件通過(guò)我們之前一分鐘入門(mén)的示例activiti-explorer應(yīng)用導(dǎo)入進(jìn)去,查看它的流程圖,并完整執(zhí)行一遍流程。
在編寫(xiě)這個(gè)Demo之前,至少要了解Activiti與Spring如何集成、XxxService各自的任務(wù)與作用,并完成上一章的Demo。
首先,我們就來(lái)編寫(xiě)這個(gè)流程的bpmn20.xml文件。
<definitions id="definitions" targetNamespace="http://activiti.org/bpmn20" xmlns:activiti="http://activiti.org/bpmn" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"> <process id="financialReport" name="Monthly financial report reminderprocess"> <startEvent id="theStart" /> <sequenceFlow id='flow1' sourceRef='theStart' targetRef='writeReportTask' />
<userTask id="writeReportTask" name="Write monthly financial report" > <documentation> Write monthly financial reportfor publication to shareholders. </documentation> <potentialOwner> <resourceAssignmentExpression> <formalExpression>sales</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> <sequenceFlow id='flow2' sourceRef='writeReportTask' targetRef='verifyReportTask' /> <userTask id="verifyReportTask" name="Verify monthly financial report" > <documentation> Verify monthly financial reportcomposed by the accountancy department. This financial report is goingto be sent to all the company shareholders. </documentation> <potentialOwner> <resourceAssignmentExpression> <formalExpression>management</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> <sequenceFlow id='flow3' sourceRef='verifyReportTask' targetRef='theEnd' /> <endEvent id="theEnd" /> </process></definitions>
這里對(duì)部分代碼進(jìn)行解釋。
1) 文件的開(kāi)頭部分,這里的id對(duì)于Activiti來(lái)說(shuō), 應(yīng)該叫做key。創(chuàng)建流程實(shí)例時(shí),會(huì)根據(jù)此id來(lái)得到這個(gè)流程。
2) 開(kāi)始流程。
3) 順序流(就是連接各個(gè)節(jié)點(diǎn)的指向線(xiàn))
sourceRef和targetRef分別為起始節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)。
4) 描述用戶(hù)任務(wù)
id為該用戶(hù)任務(wù)的標(biāo)識(shí)。
documentation為該用戶(hù)任務(wù)的描述。
5) 分配用戶(hù)
可以把任務(wù)分配給指定的用戶(hù),也可以分配給指定的組,并且可以有多個(gè),詳見(jiàn)用戶(hù)手冊(cè)。
這里配置了數(shù)據(jù)源、事務(wù)管理、流程引擎及幾個(gè)必要的xxxService。這里數(shù)據(jù)源使用的是dbcp。數(shù)據(jù)庫(kù)信息就配置成你自己本地?cái)?shù)據(jù)庫(kù)的信息,如果不會(huì)配置。
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/activiti"/>
<property name="username" value="root"/>
<property name="passWord" value="root"/>
<property name="initialSize" value="20" />
<property name="maxActive" value="50"/>
<property name="maxIdle" value="20"/>
<property name="minIdle" value="10"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="repositoryService" factory-bean="processEngine"
factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine"
factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine"
factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine"
factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine"
factory-method="getManagementService" />
<tx:annotation-driven transaction-manager="transactionManager" />
注:bpmn20.xml文件中用到了兩個(gè)用戶(hù)組(sales、management),是因?yàn)槲覀儐?dòng)Tomcat運(yùn)行activiti-explorer應(yīng)用初始化時(shí)自動(dòng)就會(huì)往數(shù)據(jù)庫(kù)里添加一些數(shù)據(jù),其中用戶(hù)組的表中就會(huì)添加幾條記錄,其中就包括這兩個(gè)組,所以不用管它怎么來(lái)的,總之?dāng)?shù)據(jù)庫(kù)里有這兩個(gè)組就對(duì)了。而應(yīng)用默認(rèn)使用的是內(nèi)存數(shù)據(jù)庫(kù),服務(wù)一停止數(shù)據(jù)也就沒(méi)有了。所以為了進(jìn)行單元測(cè)試,需要按前面講的修改數(shù)據(jù)庫(kù)配置的方法:
把a(bǔ)ctiviti-explorer應(yīng)用的數(shù)據(jù)庫(kù)配置改成你自己的本地?cái)?shù)據(jù)庫(kù)的信息,我使用的是Mysql數(shù)據(jù)庫(kù)。再啟動(dòng)tomcat運(yùn)行應(yīng)用(目的就是為了讓數(shù)據(jù)庫(kù)有數(shù)據(jù)),這時(shí)你的本地?cái)?shù)據(jù)庫(kù)就有數(shù)據(jù)了,可以編寫(xiě)測(cè)試用例進(jìn)行單元測(cè)試了。
1) 讀取Spring配置文件,注入流程所需的Service
2) 編寫(xiě)測(cè)試方法
@Test
public void monthtest() {
// 部署流程定義
repositoryService.createDeployment().addClasspathResource("myProcess.bpmn20.xml").deploy();
// 啟動(dòng)流程實(shí)例
String procId = runtimeService.startProcessInstanceByKey("financialReport").getId();
// 獲得第一個(gè)任務(wù)
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("sales").list();
for (Task task : tasks) {
System.out.println("Following task is available for sales group: " + task.getName());
// 認(rèn)領(lǐng)任務(wù)這里由foozie認(rèn)領(lǐng),因?yàn)?u>fozzie是sales組的成員
taskService.claim(task.getId(), "fozzie");
}
// 查看fozzie現(xiàn)在是否能夠獲取到該任務(wù)
tasks = taskService.createTaskQuery().taskAssignee("fozzie").list();
for (Task task : tasks) {
System.out.println("Task for fozzie: " + task.getName());
// 執(zhí)行(完成)任務(wù)
taskService.complete(task.getId());
}
// 現(xiàn)在fozzie的可執(zhí)行任務(wù)數(shù)就為0了
System.out.println("Number of tasks for fozzie: "
+ taskService.createTaskQuery().taskAssignee("fozzie").count());
// 獲得第二個(gè)任務(wù)
tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
for (Task task : tasks) {
System.out.println("Following task is available for accountancy group:" + task.getName());
// 認(rèn)領(lǐng)任務(wù)這里由kermit認(rèn)領(lǐng),因?yàn)?u>kermit是management組的成員
taskService.claim(task.getId(), "kermit");
}
// 完成第二個(gè)任務(wù)結(jié)束流程
for (Task task : tasks) {
taskService.complete(task.getId());
}
// 核實(shí)流程是否結(jié)束,輸出流程結(jié)束時(shí)間
HistoricProcessInstancehistoricProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(procId).singleResult();
System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());
}
3) 運(yùn)行示例,Demo完成。這就是一個(gè)最簡(jiǎn)單的流程,通過(guò)這個(gè)流程,了解到Activiti中流程是怎么流的,我們?cè)趺纯刂扑?/p>
1) 單元測(cè)試完成后,我們可以將該bpmn20.xml文件導(dǎo)入之前我們部署的activiti-explorer應(yīng)用中:點(diǎn)擊流程的流程設(shè)計(jì)工作區(qū),點(diǎn)擊導(dǎo)入,將剛才我們編寫(xiě)的文件導(dǎo)入進(jìn)去。
2) 導(dǎo)入之后在右上角點(diǎn)擊部署。
3) 在已部署流程定義中我們可以看到這個(gè)流程,及它的流程圖。
4) 點(diǎn)擊啟動(dòng)流程,該流程就會(huì)被啟動(dòng),再點(diǎn)擊任務(wù)中,列隊(duì)就會(huì)有該任務(wù)了,而且是分配給sales的,這正是我們定義流程時(shí)所分配給的用戶(hù)組啊。注意,現(xiàn)在只有sales組的用戶(hù)才可以看到此任務(wù)!
5) sales組的用戶(hù)進(jìn)入之后點(diǎn)擊“簽收”,該任務(wù)就分配給該用戶(hù)了,然后該用戶(hù)就可以進(jìn)行處理,也就是在代辦任務(wù)和受邀里。
6) 進(jìn)去之后點(diǎn)擊完成任務(wù),該任務(wù)就流到下一個(gè)節(jié)點(diǎn),也就是流轉(zhuǎn)到management組中去了,要由management組的用戶(hù)去處理。
7) 于是這時(shí)候,隊(duì)列中management組就有一個(gè)新的任務(wù)了,等待management組的成員來(lái)“簽收”,并完成任務(wù)。該流程也就結(jié)束了。
8) 此時(shí)就可以查看歷史任務(wù)了,就是我們這里的“已歸檔”。用戶(hù)完成的任務(wù)會(huì)在這里顯示。
這就是整個(gè)Demo的編寫(xiě)、測(cè)試過(guò)程。這樣一個(gè)小小的流程基本能夠體現(xiàn)出Activiti的功能及使用方法。
Activiti有一個(gè)Eclipse插件,Activiti Eclipse Designer,可用于圖形化建模、測(cè)試、部署 BPMN 2.0的流程。這樣就不用我們自己去編寫(xiě)繁瑣的流程文件了。具體安裝方法見(jiàn)手冊(cè)。
打開(kāi) Help-> Install New Software.在如下面板中 , 點(diǎn)擊 Add 按鈕, 然后填入下列字段:
Name: Activiti BPMN 2.0 designer
Location: http://activiti.org/designer/update/
然后一步步的安裝就可以了。
至于如何使用,文檔中介紹的非常詳細(xì),這里基于我初次使用的經(jīng)驗(yàn),強(qiáng)調(diào)幾點(diǎn):
1) 安裝之后將“保存bpmn文件時(shí)創(chuàng)建圖片文件”勾選上。這樣你每次保存bpmn文件時(shí),會(huì)為你自動(dòng)創(chuàng)建圖片文件。
2) 節(jié)點(diǎn)的所有屬性可在properties控制臺(tái)中設(shè)置。
3) 在使用設(shè)計(jì)器之前,先去鉆研BPNM2.0規(guī)范吧,了解BPNM結(jié)構(gòu)(可參看用戶(hù)手冊(cè)),才能畫(huà)出符合邏輯且完美的流程圖。
該例為使用Activiti Eclipse Designer設(shè)計(jì)的“請(qǐng)假”流程圖。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注