在使用Jbpm時,我們通常的作法是把流程定義存儲到數據庫中,然後在程序中從數據庫中加載流程定義,把流程定義存儲到數據庫中的過程就叫做流程定義的部署。
Jbpm爲其流程定義使用了一種打包機制,即把流程定義及其相關文件打包到一個zip格式的壓縮包中,稱爲流程檔案,然後通過部署這個壓縮包把流程定義存儲到數據庫。
注:以下內容基於數據庫表已經存在的基礎,數據庫表的創建在其他文章中單獨描述。
一、Ant任務完成打包和部署
Jbpm發行包中定義了ant任務來完成打包和部署任務。
1.打包流程檔案
<target name="build.processes" depends="compile" description="builds the example processes">
<mkdir dir="build/websale/classes" />
<copy todir="build/websale">
<fileset dir="src/process.examples/websale.par" />
</copy>
<copy todir="build/websale/classes">
<fileset dir="build/classes.examples" includes="org/jbpm/websale/**" />
</copy>
<zip destfile="build/websale.process">
<fileset dir="build/websale" />
</zip>
</target>
這個任務是用來打包流程定義的,它依賴於compile任務,compile是用來編譯Jbpm項目的,如果我們自己的項目已經有獨立的編譯機制,則無需依賴這個任務,只需要拷貝相關文件到指定的打包目錄即可。通過這個任務我們可以看到,流程檔案中不僅僅包括了流程定義文件,還可以包括其它相關文件,如流程定義的圖片文件、流程定義中Action和Task等的實現類的Java ByteCode(即.class文件)等信息。在上面任務中把流程檔案打包爲websale.process文件,實際使用時流程檔案文件的擴展名可以任意。
有以下幾點需要注意:
每個流程檔案只能打包一個流程定義,如果有多個流程定義則需要打包多個流程檔案;
在每個流程檔案包的第一層中必須包含流程定義的核心文件processdefinition.xml;
.class文件必須存在於classes目錄中。
如下結構:
2.部署流程檔案
(1)第一種方式
我們可以參考build.depoly.xml(位於入門套件解壓後的jbpm文件夾中)中的deploy.processes任務,如下:
這個任務是用來部署流程檔案的,它依賴declare.jbpm.tasks任務(declare.jbpm.tasks任務定義了Jbpm實現的有關部署流程定義的的Ant任務,如標籤中的deployprocess,我們暫且不討論,後面會介紹該任務)。首先它會調用build.xml中的build.processes任務來打包流程檔案,然後會使用Jbpm自己實現的ant任務(標籤deployprocess)來部署流程檔案。部署時需要兩個配置文件hibernate.cfg.xml(位於入門套件解壓後的jbpm/src/config.files文件夾中)和create.db.hibernate.properties(位於入門套件解壓後的jbpm/src/resources/hsqldb文件夾中),這兩個文件指定了Hibernate的配置信息,可以直接從發行包中拷貝使用,具體位置和數據庫連接信息根據實際情況調整。任務中所發佈的流程檔案文件在build目錄下,擴展名爲process,這些可以根據實際情況並結合打包任務build.processes進行相應調整。
下面我們說一下declare.jbpm.tasks,如下:
在我們項目中使用時可以刪除<ant antfile="build.xml" target="build" />,它僅僅是用來構建Jbpm項目的。
declare.jbpm.tasks任務的主要工作是定義了Jbpm實現的有關部署流程定義的的Ant任務標籤,它需要配置文件jbpm.ant.tasks.properties(位於入門套件解壓後的jbpm/src/java.jbpm/org/jbpm/ant文件夾中),可以直接從發行包中拷貝使用,具體位置根據實際情況設定。classpath.ant定義爲指向Jbpm庫(還包括相關庫,如Hibernate相關庫)。
(2)第二種方式
呵呵,第一種方式看起來是不是有點煩瑣:)這只是發行包種採用的方式,對於我們使用時,可以使用下面的稍簡化方式:
這種方式只是集成了第一種方式中的兩個任務。
二、通過編程來完成部署
除了通過Jbpm提供的Ant任務進行流程定義的部署之外,還可以通過編程來完成。如下代碼:
以上代碼的執行還需要依賴Hibernate的配置文件hibernate.cfg.xml。
流程檔案部署後,就不再需要這個壓縮包及其中的文件了,這是爲什麼?這是因爲數據庫中的jbpm_bytearray和jbpm_byteblock兩張表存儲了流程檔案的文件內容,它們把流程檔案中的文件拆開了存到了數據庫。jbpm-bytearray存儲了流程檔案的目錄,jbpm_bytebolck則是將文件的二進制內容存了進去。對於流程檔案中包含的流程定義中Action和Task等Java ByteCode信息(.class文件),引擎會從數據庫讀出byte[]數組然後作爲類加載,如果你的類存在於引擎可見的classpath,那麼就會從那裏加載,所以說流程所需的.class文件可以打包到流程檔案,也可以不打包到流程檔案,而是放在你的classpath目錄下。