基於BPMN2.0的工單系統架構設計(下)

版權聲明: 本文爲博主原創文章,未經博主容許不得轉載。關注公衆號技術匯(ID: jishuhui_2015) 可聯繫到做者。架構

在上兩篇文章中,介紹了BPMN2.0和工做流定義語言(如下簡稱WDL),以及工單系統的業務流程設計。本文是工單系統系列的最後一篇,着重講解工單系統的程序設計。框架

由於全部流程的配置和定義都在WDL文件中,因此必然會引入關於WDL的解析層,這是整個工單系統的基礎。工具

除了解析層,還少不了執行層的存在,整個工單流程就是靠執行層去推進的。post

若是對Activiti的源碼有所鑽研的讀者,看完此篇文章後,會以爲很是相似,這是不能否認的,站在巨人的肩膀上才能看得更遠更全。ui

Activiti:一直被模仿,從未被超越。spa

1、BpmnModel

這部份內容主要介紹WDL中各元素的設計,它們有個統一的名字:BpmnModel。這個名字來源於Activiti的源碼,在此沿用之。架構設計

根據基於BPMN2.0的工單系統架構設計(上)文章中的介紹,WDL文件中能夠提取五個關鍵的基本要素:設計

一、Definitions,這個是根元素,無可厚非;code

二、Message,關於消息的定義,是Definitions的子元素,能夠有多個消息的定義;cdn

三、Process,整個流程的定義,也是Definitions的子元素,暫不支持SubProcess;

四、EventDefinition,事件定義,與其餘元素區別較大,因此單獨提取出來,包括了消息事件,定時事件;

六、FlowNode,能夠理解爲是Process的各個子元素,好比SequenceFlow,Task,Gateway等等。

基本元素繼承關係

BaseElement是最頂層的抽象,id和elementName做爲共有屬性,同時有一個validate校驗方法,對元素的合法性進行校驗。

由於是須要將一整個WDL文件解析出來,這其中就會包含不少元素對象,最後還須要一個真正意義上的BpmnModel進行裝載,以下:

BpmnModel

在上圖的BpmnModel中,Process很是關鍵,由於其下有衆多子元素(FlowNode),找到了Process就能找到其餘的子元素。因此,Process的另一個做用就是元素容器(Container),容器裏面能夠維護本身的子元素,以下是接口定義:

FlowNodeContainer

2、WDL解析器

Activiti有一個強大之處在於能進行可視化流程配置,只要瞭解BPMN2.0規範,就能很輕鬆的配置出想要的流程。

固然,本工單系統是沒有必要去實現這個功能的,因此這一部分側重講解從WDL文件到BpmnModel的過程。

筆者從Activiti源碼中看到了有一個interface,當中定義了全部Activiti支持的元素,固然也涵蓋了上述提到的那些基本元素。該類名是BpmnXMLConstants,其內容較大,故不在此展現了。

筆者沿用了這個類,可是作了一點小改進:將元素標籤和元素屬性分開,作成了兩個interface,以下所示:

BpmnXmlConstants

Activiti中使用的解析工具是JDK自帶的XMLStream,大概是不想引入新的依賴,增長開發者的負擔吧!筆者使用的是Dom4j,而不是XMLStream。基於這一點考慮,筆者在設計的時候抽象出了頂層接口,以下所示:

Parser

BaseBpmnXMLParser接口中的泛型即爲元素解析對象,好比XMLStreamReader,Dom4j中的Element對象等等。doParse方法即爲解析的入口,WDL中所支持的各種元素標籤都將有一個Parser實現。

3、WDL轉換器

這一個部分的主要功能是WDL與BpmnModel的互相轉換。

Converter

與解析器的設計相似,也是要根據XML的解析工具進行實現。

在Converter接口中,定義了三個方法,其中兩個是WDL和BpmnModel的互轉,目前僅實現了convertToBpmnModel。

還有一個是對BpmnModel的校驗方法,校驗不經過直接拋出Exception。

對於轉換成功的BpmnModel,會存放在一個容器內,稱之爲BpmnModelContainer。

BpmnModelContainer

這個Container接口定義了對BpmnModel基本的添加,移除和查找方法。另外還有三個方法須要解釋一下:

一、next。指示工單流程的下一個步驟,返回下一個步驟的元素。由於可能存在ParallelGateway,這就意味着下一個步驟將會有多個節點同步執行,因此返回結果是一個Queue對象,存放着下一個步驟要執行的節點元素。

二、conditionParse。在基於BPMN2.0的工單系統架構設計(上)文章中曾說起到了WDL中表達式的解析。在container中,此方法主要解析的是網關的執行條件,配合next方法使用。

三、fill。這個方法是用於填充Container,該方法的調用時機是構造BpmnModelContainer的時候,固然是要藉助WDL轉換器實現。以下所示:

@Configuration
@EnableConfigurationProperties(WorkflowProperties.class)
public class BpmnXmlManager {

    /** * 構造BpmnModelContainer,解析WDL文件,填充BpmnModel */
    @Bean
    public BpmnModelContainer bpmnContainer(WorkflowProperties workflowProperties, BaseBpmnXMLConverter converter) throws Exception {
        BpmnModelContainer container = new BpmnModelContainer(workflowProperties, converter);
        container.fill();
        return container;
    }

    /** * 構造XML解析工廠,默認是Dom4j的解析方式 */
    @Bean
    @ConditionalOnMissingBean(BpmnXMLParserFactory.class)
    public Dom4jParserFactory xmlParserFactory() {
        return new Dom4jParserFactory();
    }

    /** * 構造XML轉換工廠,默認是Dom4j的轉換方式 */
    @Bean
    @ConditionalOnMissingBean(BaseBpmnXMLConverter.class)
    public Dom4jConverter xmlConverter() {
        return new Dom4jConverter();
    }
}
複製代碼

4、工單執行

前三部分工做完成以後,工單就能夠正常流轉了。

service
一、 start,工單的發起;

二、accept,後臺操做人員接單;

三、doTask,執行工單節點(用戶任務);

四、getWorkOrderDetail,獲取工單詳情,包含工單基本信息,工單動態,工單客戶信息,工單任務列表等;

五、addWorkOrderProgress,添加一條工單進度信息,方便客戶端查看工單進度;

六、nextElement,查找下一個工單節點,查找範圍涵蓋了Process的全部子元素,是推進工單流程的重要方法。

對於WDL中的Task和Event都有設計其對應的Runner,用於執行其內在的業務邏輯。

runner

在Runner執行期間,會遇到一些定時任務,好比定時邊界捕獲事件,筆者使用了Quartz開發框架,整合了SpringBoot進行定時任務的管理。

5、總結

本篇文章對工單系統的程序設計作了較爲詳細的講解,對於整個工單系統的設計也就到此爲止了。若是筆者能通讀工單系統設計系列的三篇文章,對於從此的工單系統設計也將會有所啓發。

關注咱們
相關文章
相關標籤/搜索