实际项目中的工作流工作原理

现在公司开发的项目中用到了工作流,在进入本公司之前本屌丝还没有接触过工作流,所以对工作流的工作原理一直很感兴趣,一直在默默的学习,终于有一天本屌突然看懂了源码(大雾,现在我觉得看懂了可能只是骗我自己,好可怕),而且今天终于有时间来整理一下工作流,以备大家指正。
本屌公司之前的CTO是阿里的大牛,所以整个公司的项目框架我们可以看出很多阿里的风格,能接触这么厉害的技术,本屌心里好开心,废话不说了,回归正题:
项目中应用Spring MVC+Maven,简单粗暴,工作流的作用呢,就是确保数据流程完整,保持状态一致正确,有倒计时功能的状态可以自动更新状态,发布事件。如果有监听事件的处理器就可以调用相关动作了。

那么工作流除了业务环境中的手动推进,今天我们主要讲的就是超时事件,当前状态可能只能保持10分钟或者配置文件中的特定时间,超过此事件状态失效,状态流转为time_out并且发布状态超时事件。我们准备讲一个实际状态,审核状态,如果审核中的状态持续了1个小时而没有人手动审核的话,超时。

第一。我们定义了业务的状态流转模型

我们可以看到等待复核状态后面有三个相应状态,标红的复核超时就是工作流推动的。

第二,把模型转换成XML配置

我们在项目中按照业务流程把需要工作流推动状态的几个模型的状态流转转换为工作流的模板定义。看XML


transit_task
运输流程
start
WF03

<wf_action_list>
    <wf_action>
        <pvg_required>
            <key>*</key>
            <user>*</user>
        </pvg_required>
        <need_lock>true</need_lock>
        <name>start</name>
        <desc>开始</desc>
        <executer_name>BLANK_ACTION</executer_name>
        <next_status_list>
            <next_status>
                <caseExpr>*</caseExpr>
                <status>in_transit</status>
            </next_status>
        </next_status_list>
    </wf_action>



<wf_status_list>
    <!-- 取消开始运输
    <wf_status>
        <name>wait_transit</name>
        <desc>待运输</desc>
        <next_action_list>
            <next_action>
                <name>start_transit</name>
            </next_action>
        </next_action_list>
        <action_relation>XOR</action_relation>
        <finish>false</finish>
    </wf_status>
    --><wf_status>
        <name>force_discard</name>
        <desc>强制作废</desc>
        <finish>true</finish>
    </wf_status>
</wf_status_list>

屌大的一眼看明白了这个XML配置的主要信息是什么了,一个是wf_status_list,一个是wf_action_list。他们的list顺序就代表状态的流转顺序,不能打乱。

第三。加载我们的工作流实例配置XML

下面这个xml配置就是启动ConfigLoader扫描我们手动配置的工作流的模板的a.b.c.xml文件(即 上面我们说的wf_status_list 和wf_action_list);

<bean id="wf_configLoader" class="com.opengroup.hongshi.wf.biz.def.config.ConfigLoader"  scope="singleton"  init-method="init" >
    <constructor-arg>
        <list>
            <value>wf_def_config/a.xml</value>
            <value>wf_def_config/b.xml</value>
            <value>wf_def_config/c.xml</value>
        </list>
    </constructor-arg>
</bean>

我们看ConfigLoader的代码

/**
* 初始化
*/
public void init() {
try {
XStream xstream = new XStream();//这个类厉害了。到现在我还没搞明白这个类是干什么的安静
xstream.processAnnotations(WfDef.class);//WfDef这个类里面包装了所有的a或者b或者c工作流XML里面的wf_status_list 和wf_action_list,
xstream.processAnnotations(WfAction.class);
xstream.processAnnotations(WfStatus.class);
xstream.processAnnotations(NextStatus.class);
xstream.processAnnotations(NextAction.class);
xstream.processAnnotations(PvgRequired.class);//我们就假装这个xstream 把这几个对象里面的标签全部预存起来了,从xml里面读取之后再全部回填到对象里面
xstream.autodetectAnnotations(true);

        for (String file : files) {//files是我们构造函数里面的 a b c 那三个xml
            String fileContent = ClasspathFileUtil.readAsStr(file);//残忍,xml被读成了String
            fileContent = StringUtil.fillReplacement(fileContent, wfProperties);//真残忍,String中的占位符都被实际的配置内容替换掉了
            WfDef wfDef = (WfDef) xstream.fromXML(fileContent);//吊炸天的一步操作,当初读取的所有XML都赋值到该对象的相应标签里面了
            wfDef.init();
            if (wfDef.isAllValid()) {
                WfDefRegister.register(wfDef);
            } else {
                throw new CriticalSystemError("工作流定义的领域对象值校验不通过");
            }

最近本屌丝正好在学习core java,第二卷就讲到XML的读写,关于XML也只是皮毛,有很多实际项目中的应用已经超乎书内部分讲的了,所以我们只讲配置。

Spring MVC 最喜欢的事情是什么,就是配置XML,虽然已经有关于注释的配置,但是我们项目还是有很多配置要手动配置XML,为什么呢,因为XML配置明显易懂,可以集中管理。缺点呢就是打字费手。看XML配置

第四,工作流的实现机制

那么工作流到底是怎么检测到超时实例的呢。

那就要从实现机制说起了,Spring有个很神奇的功能叫做Quartz.相信很多盆友都了解,关于Quartz以后单独讲,我们知道他就是一个定时器任务,可以在我们配置的任何时间启动,实现相应的功能。我们项目中的工作流就是依托了Quartz实现了工作流的超时动作。当我们的服务启动之后,quartz就很勤奋的一直在后台准备着,一旦到了该他启动的时候,他就会准时跑起来做自己的工作,很像准时的哨兵,到点准时巡逻。抓到超时没有完成作业的家伙一顿大棒槌砸你小胸胸(大雾!)


猜你喜欢

转载自blog.csdn.net/qq_40112624/article/details/81873068
今日推荐