activiti6.0源碼剖析之BpmnModel模型校驗器

activiti源碼剖析之BpmnModel模型校驗器

前言
BpmnModel校驗器可以用來校驗BpmnModel是否構(gòu)造成功昌简,可以對BpmnModel每一個元素進行合法校驗,除了BpmnModel構(gòu)造正確性校驗之外腻扇,我們還可以根據(jù)業(yè)務(wù)場景設(shè)計自定義模型校驗器细诸。比如業(yè)務(wù)需要流程中如果包含用戶任務(wù),那么用戶任務(wù)必須指定處理人等等,這種需求我們完全可以通過自定義模型校驗器進行實現(xiàn)。

一魂奥、BpmnModel模型校驗器初體驗

        //創(chuàng)建模型校驗器工廠
        ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
        //創(chuàng)建默認模型校驗器
        ProcessValidator processValidator = processValidatorFactory.createDefaultProcessValidator();
        //進行模型校驗
        List<ValidationError> validate = processValidator.validate(bpmnModel);
        //如果校驗錯誤集合長度大于1,則說明校驗出錯易猫,遍歷打印出錯信息
        if(validate.size()>=1){
            for (ValidationError validationError : validate) {
                System.out.println(validationError.getProblem());
                System.out.println(validationError.isWarning());
            }
        }

二、 通過源碼分析模型校驗器

通過初體驗代碼我們大致了解到具壮,模型校驗器的步驟:

1.獲取模型校驗器工廠ProcessValidatorFactory
2.通過模型校驗器工廠創(chuàng)建模型校驗器ProcessValidator
3.調(diào)用ProcessValidator模型校驗器validate方法准颓,返回校驗結(jié)果集

  • 查看processValidatorFactory.createDefaultProcessValidator()源碼
public ProcessValidator createDefaultProcessValidator() {
       ProcessValidatorImpl processValidator = new ProcessValidatorImpl();
       processValidator.addValidatorSet((new ValidatorSetFactory()).createActivitiExecutableProcessValidatorSet());
       return processValidator;
   }
  • ValidatorSetFactory()).createActivitiExecutableProcessValidatorSet()實現(xiàn)
    public ValidatorSet createActivitiExecutableProcessValidatorSet() {
        ValidatorSet validatorSet = new ValidatorSet("activiti-executable-process");
        validatorSet.addValidator(new AssociationValidator());
        ...
        validatorSet.addValidator(new FlowElementValidator());
        validatorSet.addValidator(new StartEventValidator());
        validatorSet.addValidator(new SequenceflowValidator());
        validatorSet.addValidator(new UserTaskValidator());
        .....
        validatorSet.addValidator(new DiagramInterchangeInfoValidator());
        return validatorSet;
    }

首先創(chuàng)建一個ProcessValidatorImpl對象,該對象持有元素為ValidatorSet的一個集合棺妓,顧名思義攘已,這個集合中包含著所有的校驗器,ProcessValidatorImpl進行模型校驗時怜跑,遍歷這個集合样勃,再針對每一個validatorSet中持有的所有Validator實現(xiàn)遍歷對BpmnModel模型進行校驗,并且將校驗錯誤添加到 List<ValidationError>集合中性芬,遍歷結(jié)束返回ValidationError結(jié)果集峡眶。

所以如果想實現(xiàn)自定義校驗器,只需要實現(xiàn)我們自己的ValidatorSet 然后添加到ProcessValidatorImpl對象中的validatorSets集合中植锉。那么如何實現(xiàn)自定義的ValidatorSet呢辫樱?我們先來看看ValidatorSet都有哪些東西


ValidatorSet.png

從ValidatorSet的構(gòu)成來看,校驗器的重點應(yīng)該是Validator俊庇,也就是說所有的模型校驗器都應(yīng)該實現(xiàn)Validator接口狮暑,這里我們查看Validator類結(jié)構(gòu)鸡挠,可以看出來activiti通過Validator有很多實現(xiàn),分別校驗bpmn流程文檔中不同的元素節(jié)點搬男。


Validator類結(jié)構(gòu).png

三拣展、自定義Bpmn模型校驗器實戰(zhàn)

場景:在部署流程之前需要校驗流程中的所有用戶任務(wù)是否指定辦理人

  • 第一步、定義校驗器類缔逛,繼承ProcessLevelValidator實現(xiàn)executeValidation方法
public class UserTaskValidator extends ProcessLevelValidator {
    @Override
    protected void executeValidation(BpmnModel bpmnModel, Process process, List<ValidationError> errors) {
        //獲取模型中所有的用戶任務(wù)節(jié)點
        List<UserTask> userTaskList = process.findFlowElementsOfType(UserTask.class);
        for (UserTask userTask : userTaskList) {
            //獲取用戶任務(wù)指定人
            String assignee = userTask.getAssignee();
            if(assignee == null || assignee == ""){
                //向List<ValidationError>添加校驗錯誤結(jié)果
                ValidationError validationError = new ValidationError();
                validationError.setProblem(userTask.getId()+"--->沒有指定辦理人");
                validationError.setWarning(false);

                errors.add(validationError);
            }
        }

    }
}
  • 第二步备埃、創(chuàng)建ValidatorSet封裝自定義校驗器
    
        ValidatorSet validatorSet = new ValidatorSet("Validate UserTask assigne");
        validatorSet.addValidator(new UserTaskValidator());
  • 第三步、獲取ProcessValidator的List<ValidatorSet>译株,將自定義校驗器添加進去瓜喇,對模型進行校驗
        //創(chuàng)建模型校驗器工廠
        ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
        //創(chuàng)建默認模型校驗器
        ProcessValidator processValidator = processValidatorFactory.createDefaultProcessValidator();
        //添加自定義模型校驗器
        List<ValidatorSet> validatorSets = processValidator.getValidatorSets();
        validatorSets.add(validatorSet);

        //進行模型校驗
        List<ValidationError> validate = processValidator.validate(bpmnModel);
        //如果校驗錯誤集合長度大于1,則說明校驗出錯歉糜,遍歷打印出錯信息
        if(validate.size()>=1){
            for (ValidationError validationError : validate) {
                System.out.println(validationError.getProblem());
                System.out.println(validationError.isWarning());
            }
        }
  • 查看校驗結(jié)果
    校驗結(jié)果.png

四乘寒、擴展源碼,將自定義模型檢驗器融合進activiti

此操作相當于將我們自定義的校驗器設(shè)置為全局檢驗匪补,這樣以后在部署流程文檔時伞辛,都會經(jīng)過我們自定義的模型校驗器,如果校驗出錯誤夯缺,則部署失敗蚤氏。那么應(yīng)該如何擴展呢

  • 查看ProcessEngineConfigurationImpl.class中初始化流程校驗器實現(xiàn)
    public void initProcessValidator() {
        if (this.processValidator == null) {
            this.processValidator = (new ProcessValidatorFactory()).createDefaultProcessValidator();
        }

    }

可以看到,這里先校驗processValidator開關(guān)屬性(可配置)是否為空踊兜,如果為空(用戶未設(shè)置該開關(guān)屬性)則使用默認的流程校驗器竿滨。所以我們這里通過配置processValidator開關(guān)屬性來進行擴展,當然捏境,你也可以直接擴展ProcessEngineConfigurationImpl

  • 第一步于游、自定義模型檢驗器
    這里不再重復(fù)
  • 第二步、擴展ProcessValidatorFactory,將自定義校驗器添加進去
public class ProcessValidatorFactoryExt extends ProcessValidatorFactory {
    @Override
    public ProcessValidator createDefaultProcessValidator() {
        ProcessValidator defaultProcessValidator = super.createDefaultProcessValidator();
        //將自定義校驗器添加進去
        ValidatorSet validatorSet = new ValidatorSet("Validate UserTask assigne");
        validatorSet.addValidator(new UserTaskValidator());

        defaultProcessValidator.getValidatorSets().add(validatorSet);
        return defaultProcessValidator;
    }
}
  • 第三步垫言、修改activit.cfg.xml贰剥,配置StandaloneProcessEngineConfiguration的開關(guān)屬性processValidator(這里修改activiti_context.xml也是類似的,也就是集成Spring)
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_activiti" />
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="1234" />
        <property name="databaseSchemaUpdate" value="true" />
        <!--配置流程校驗器-->
        <property name="processValidator">
            <bean  factory-bean="processValidatorFactoryExt" factory-method="createDefaultProcessValidator"/>
        </property>

    </bean>
    <bean id="processValidatorFactoryExt" class="cn.cf.activiti.shareniu.ProcessValidatorFactoryExt"/>

</beans>
  • 部署一個流程文檔,流程文檔中的用戶任務(wù)不分配處理人的結(jié)果
    部署結(jié)果.png

到這里筷频、自定義流程校驗器就剖析完畢啦蚌成,有問題的地方希望多多指出,謝謝凛捏!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末担忧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子葵袭,更是在濱河造成了極大的恐慌涵妥,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蓬网,居然都是意外死亡窒所,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門帆锋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吵取,“玉大人炭臭,你說我怎么就攤上這事丸凭。” “怎么了撮躁?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵实辑,是天一觀的道長捺氢。 經(jīng)常有香客問我,道長剪撬,這世上最難降的妖魔是什么摄乒? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮残黑,結(jié)果婚禮上馍佑,老公的妹妹穿的比我還像新娘。我一直安慰自己梨水,他們只是感情好拭荤,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疫诽,像睡著了一般舅世。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奇徒,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天歇终,我揣著相機與錄音,去河邊找鬼逼龟。 笑死,一個胖子當著我的面吹牛追葡,可吹牛的內(nèi)容都是我干的腺律。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼宜肉,長吁一口氣:“原來是場噩夢啊……” “哼匀钧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谬返,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤之斯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后遣铝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佑刷,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡莉擒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瘫絮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涨冀。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖麦萤,靈堂內(nèi)的尸體忽然破棺而出鹿鳖,到底是詐尸還是另有隱情,我是刑警寧澤壮莹,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布翅帜,位于F島的核電站,受9級特大地震影響命满,放射性物質(zhì)發(fā)生泄漏涝滴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一周荐、第九天 我趴在偏房一處隱蔽的房頂上張望狭莱。 院中可真熱鬧,春花似錦概作、人聲如沸腋妙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骤素。三九已至,卻和暖如春愚屁,著一層夾襖步出監(jiān)牢的瞬間济竹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工霎槐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留送浊,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓丘跌,卻偏偏與公主長得像袭景,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闭树,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355