zoukankan      html  css  js  c++  java
  • Flowable工作流学习

    教程地址:https://tkjohn.github.io/flowable-userguide/#bpmnConditionalSequenceFlow

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:flowable="http://flowable.org/bpmn"
                 xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
                 xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
                 xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
                 typeLanguage="http://www.w3.org/2001/XMLSchema"
                 expressionLanguage="http://www.w3.org/1999/XPath"
                 targetNamespace="http://www.flowable.org/processdef">
    
        <process id="holley-test8" name="zhl-test8" isExecutable="true">
            <documentation>后礼测试流程</documentation>
    <!--        执行监听器
                可以捕获的事件:1.流程实例的启动和结束。2.流程执行转移。3.活动的启动和结束。4.网关的启动和结束。5.中间事件的启动和结束。6.启动事件的结束,和结束事件的启动。
                <flowable:executionListener class="类名全路径" event="start"/>
                    注意:这个类需要实现org.flowable.engine.delegate.ExecutionListener接口
                <flowable:executionListener expression="${myPojo.myMethod(execution.event)}" event="end" />
                    注意:execution.event将事件作为参数传递
                执行监听器也支持使用delegateExpression。
                    <flowable:executionListener event="start" delegateExpression="${myExecutionListenerBean}" />
    -->
            <extensionElements>
                <flowable:executionListener class="com.insgeek.platform.event.holley.listener.MyExecutionListener" event="start"/>
    <!--            <flowable:eventListener events="ACTIVITY_COMPLETED" class="com.insgeek.platform.event.holley.listener.MyEventListener"/>-->
            </extensionElements>
            <!--        <extensionElements>-->
            <!--            <flowable:eventListener class="com.insgeek.platform.event.holley.listener.MyEventListener" />-->
            <!--            <flowable:eventListener delegateExpression="${testEventListener}" events="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" />-->
            <!--        </extensionElements>-->
            <startEvent id="startEvent1"/>
    
            <userTask id="task-number-01" name = "${name}任务1" flowable:formFieldValidation="true"
                      flowable:assignee="${holidayForm.name}">
    <!--                  flowable:candidateUsers="" -->
    <!--                  flowable:candidateGroups=""-->
                <extensionElements>
                    <flowable:formProperty id="days" expression="${days}" required="true" type="int" name="请假天数"/>
                    <flowable:formProperty id="name" expression="${name}" required="true" name="请假天数"/>
                    <flowable:formProperty id="id" expression="${id}" type="long" required="true" name="请假人id"/>
                </extensionElements>
            </userTask>
            <sequenceFlow id="line-number-01" sourceRef="startEvent1" targetRef="task-number-01"/>
    
            <!--        服务任务:
                        注意: flowable:class="全路径类名"
                            这个方法主要使用在service task中,此处作为测试 (指定实现了JavaDelegate或ActivityBehavior的类)
                        调用解析为委托对象(delegation object)的表达式 :delegateExpressionBean是一个实现了JavaDelegate接口的bean,定义在Spring容器中
                            <serviceTask id="serviceTask" flowable:delegateExpression="${delegateExpressionBean}"
                        调用方法表达式(method expression): 将在名为printer的对象上调用printMessage方法(不带参数)
                            <serviceTask id="javaService" name="My Java Service Task" flowable:expression="${printer.printMessage()}" />
                            将在名为printer的对象上调用printMessage方法。传递的第一个参数为DelegateExecution,名为execution,在表达式上下文中默认可用。传递的第二个参数,
                                是当前执行中,名为myVar变量的值。
                            <serviceTask id="javaService" name="My Java Service Task" flowable:expression="${printer.printMessage(execution, myVar)}" />
                        对值表达式(value expression)求值 会调用名为split的bean的ready参数的getter方法,getReady(不带参数)。该对象会被解析为执行的流程变量或(如果可用的话)Spring上下文中的bean
                            <serviceTask id="javaService" name="My Java Service Task" flowable:expression="${split.ready}" />
                        只会为serviceTask上定义的Java类创建一个实例。所有流程实例共享同一个类实例,用于调用execute(DelegateExecution)。这意味着该类不能有任何成员变量,
                            并需要是线程安全的,因为它可能会在不同线程中同时执行。这也影响了字段注入的使用方法。
    
                        flowable:class和flowable:delegateExpression支持字段注入,如下:
                            <extensionElements> <flowable:field name="text" stringValue="Hello World" /> </extensionElements>
                            对于较长文本:
                            <extensionElements> <flowable:field name="text"> <flowable:string> This is a long string </flowable:string> </flowable:field></extensionElements>
                        <extensionElements>
                            <flowable:field name="text1">
                              <flowable:expression>${genderBean.getGenderString(gender)}</flowable:expression>
                            </flowable:field>
                            <flowable:field name="text2">
                               <flowable:expression>Hello ${gender == 'male' ? 'Mr.' : 'Mrs.'} ${name}</flowable:expression>
                            </flowable:field>
                          </ extensionElements>
                        另外,为避免XML太过冗长,可以将表达式设置为属性,而不是子元素。
    
                            <flowable:field name="text1" expression="${genderBean.getGenderString(gender)}" />
                            <flowable:field name="text1" expression="Hello ${gender == 'male' ? 'Mr.' : 'Mrs.'} ${name}" />
            -->
    
            <!-- 方法表达式(method expression)调用 bean中的方法-->
            <serviceTask id="task-number-02" name="服务任务1" flowable:class="com.insgeek.platform.event.holley.task.TestServiceTaskDelegate">
    <!--          flowable:expression="${holidayForm.toString()}"  -->
                <extensionElements>
                    <flowable:formProperty id="approve" expression="${approve}" required="true" type="boolean" name="审批结果"/>
                    <flowable:formProperty id="days" expression="${days}" required="true" type="int" name="请假天数"/>
                </extensionElements>
            </serviceTask>
    
            <sequenceFlow id="line-number-02" sourceRef="task-number-01" targetRef="task-number-02">
                <extensionElements>
                    <!--                流程转移时执行监听器
                        在流程执行转移时被调用。请注意listener元素并未定义event,因为在转移上只会触发take事件。当监听器定义在转移上时,event属性的值将被忽略
                    -->
                    <flowable:executionListener class="com.insgeek.platform.event.holley.listener.MyExecutionListener" />
                </extensionElements>
            </sequenceFlow>
    
            <!--        条件顺序流:
                            条件顺序流的XML表示格式为含有conditionExpression(条件表达式)子元素的普通顺序流。
                                请注意目前只支持tFormalExpressions可以省略xsi:type=""定义,默认为唯一支持的表达式类型
                                目前conditionalExpressions只能使用UEL。使用的表达式需要能解析为boolean值,否则当计算条件时会抛出异常。
                        这个例子通过典型的JavaBean的方式,使用getter引用流程变量的数据
                            <conditionExpression xsi:type="tFormalExpression"> <![CDATA[${order.price > 100 && order.price < 250}]]> </conditionExpression>
                        这个例子调用了一个解析为boolean值的方法:
                            <conditionExpression xsi:type="tFormalExpression"> <![CDATA[${order.isStandardOrder()}]]> </conditionExpression>
            -->
            <exclusiveGateway id="gateway-number-01"/>
    
            <sequenceFlow id="line-number-03" sourceRef="task-number-02" targetRef="gateway-number-01"/>
    
            <!--        任务监听器:用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式。*只能*在流程定义中作为用户任务的子元素
                        任务监听器包含下列属性:
                            event(事件)(必填):触发任务监听器的任务事件类型。可用的事件有:
                            create(创建):当任务已经创建,并且所有任务参数都已经设置时触发。
                            assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,在触发create事件之前,会首先触发assignment事件。
                                这顺序看起来不太自然,但是有实际原因的:当收到create事件时,我们通常希望能看到任务的所有参数,包括办理人。
                            complete(完成):当任务已经完成,从运行时数据中删除前触发。
                            delete(删除):在任务即将被删除前触发。请注意任务由completeTask正常完成时也会触发。
                            class:需要调用的委托类。这个类必须实现org.flowable.engine.delegate.TaskListener接口。
                        expression:(不能与class属性一起使用):指定在事件发生时要执行的表达式。可以为被调用的对象传递DelegateTask对象与事件名(使用task.eventName)作为参数。
                            <flowable:taskListener event="create" expression="${myObject.callMethod(task, task.eventName)}" />
                        delegateExpression:指定一个能够解析为TaskListener接口实现类的对象的表达式。与服务任务类似。
                            <flowable:taskListener event="create" delegateExpression="${myTaskListenerBean}" />
            -->
            <userTask id="task-number-03" name="${name}任务2" flowable:assignee="zhl" >
    <!--       flowable:candidateUsers="user1,user2" 当使用候选人分配时,会创建一个任务,但是任务中的assignee的值为null。
                而且如果同时配置flowable:assignee和flowable:candidateUsers,则只会创建flowable:assignee的任务     -->
                <extensionElements>
                    <!--                任务监听器,可以在任务监听器中动态分配用户-->
                    <flowable:taskListener event="complete" class="com.insgeek.platform.event.holley.listener.MyAssignmentHandlerTaskListener" />
                    <!--                活动结束时执行监听器-->
                    <flowable:executionListener expression="${myExpressionExecutionListener.test(execution.eventName)}" event="end" />
    
                </extensionElements>
    <!--            指派具体用户      -->
    <!--            <humanPerformer>-->
    <!--                <resourceAssignmentExpression>-->
    <!--                    <formalExpression>test</formalExpression>-->
    <!--                </resourceAssignmentExpression>-->
    <!--            </humanPerformer>-->
            </userTask>
    
            <userTask id="task-number-04" name="${name}任务4" flowable:candidateUsers="aaa,bbb">
    <!--            flowable:assignee="${name}"-->
                <extensionElements>
                    <flowable:executionListener event="start" expression=" ${rejectExecutionListener.test(execution)}"/>
    <!--                添加一个在事件create时的监听器,在监听器中可以将该事件分配给其它人,
                    分配之后,原处理人没有权限了,但此时在ru_identityLink表中还会为之前的处理人创建N条数据(假设实例是Q个,如果是m个候选人的话,n=(m+1)*Q。如果是指定的某个处理人,则n=Q)-->
                    <flowable:taskListener event="create" class = "com.insgeek.platform.event.holley.listener.AssignmentTaskListener"/>
                </extensionElements>
                <!--       多实例时,会给每个指派的用户创建数量等同于assigneeList长度的并行任务,只是每一个执行任务都有一个名为user的(局部)流程变量,含有集合userList中的一项值   -->
                <multiInstanceLoopCharacteristics isSequential="false"
                                                  flowable:collection="${myTest.getUsers(execution)}" flowable:elementVariable="user" >
    <!--                                              flowable:collection="userList" flowable:elementVariable="user" >-->
                    <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.3 }</completionCondition>
                </multiInstanceLoopCharacteristics>
            </userTask>
    
            <sequenceFlow id="line-number-04" sourceRef="gateway-number-01" targetRef="task-number-03" >
    <!--            注意:条件流下面添加执行监听器时,顺序一定要放在条件标签上面,否则会报错        -->
                <extensionElements>
                    <!--                流程转移时执行监听器
                        在流程执行转移时被调用。请注意listener元素并未定义event,因为在转移上只会触发take事件。当监听器定义在转移上时,event属性的值将被忽略
                    -->
                    <flowable:executionListener class="com.insgeek.platform.event.holley.listener.MyExecutionListener2" />
                </extensionElements>
                <conditionExpression xsi:type="tFormalExpression"> <![CDATA[ ${days > 3} ]]> </conditionExpression>
            </sequenceFlow>
            <sequenceFlow id="line-number-05" sourceRef="gateway-number-01" targetRef="task-number-04">
                <extensionElements>
                    <!--                流程转移时执行监听器
                        在流程执行转移时被调用。请注意listener元素并未定义event,因为在转移上只会触发take事件。当监听器定义在转移上时,event属性的值将被忽略
                    -->
                    <flowable:executionListener class="com.insgeek.platform.event.holley.listener.MyExecutionListener3" />
                </extensionElements>
                <conditionExpression xsi:type="tFormalExpression"> <![CDATA[ ${days <= 3} ]]> </conditionExpression>
            </sequenceFlow>
    
    
            <endEvent id="endEvent1">
                <extensionElements>
    
                    <flowable:executionListener
                            class="com.insgeek.platform.event.holley.listener.MyEndExecutionListener" event="end"/>
    
                </extensionElements>
            </endEvent>
    
            <sequenceFlow id="line-number-06" sourceRef="task-number-03" targetRef="endEvent1"/>
    
            <sequenceFlow id="line-number-07" sourceRef="task-number-04" targetRef="endEvent1" />
    
            <!--        多实例:网关与事件不能设置为多实例。
                            按照BPMN2.0规范的要求,用于为每个实例创建执行的父执行,会提供下列变量:
                            nrOfInstances:实例总数。
                            nrOfActiveInstances:当前活动的(即未完成的),实例数量。对于顺序多实例,这个值总为1。
                            nrOfCompletedInstances:已完成的实例数量。
                            可以调用execution.getVariable(x)方法获取这些值。
                        每个被创建的执行,都有局部变量(对其他执行不可见,也不存储在流程实例级别)
                        loopCounter:给定实例在for-each循环中的index。可以通过Flowable的elementIndexVariable属性为loopCounter变量重命名
    
            -->
    
        </process>
    </definitions>

    注意事项: 

      1.在条件流上添加执行监听器时,一定要保证extensionElements元素放在conditionExpression元素之前,否则会报错,正确顺序如下:

    <sequenceFlow id="line-number-04" sourceRef="gateway-number-01" targetRef="task-number-03" >
    <!--            注意:条件流下面添加执行监听器时,顺序一定要放在条件标签上面,否则会报错        -->
                <extensionElements>
                    <!--                流程转移时执行监听器
                        在流程执行转移时被调用。请注意listener元素并未定义event,因为在转移上只会触发take事件。当监听器定义在转移上时,event属性的值将被忽略
                    -->
                    <flowable:executionListener class="com.insgeek.platform.event.holley.listener.MyExecutionListener" />
                </extensionElements>
                <conditionExpression xsi:type="tFormalExpression"> <![CDATA[ ${days > 3} ]]> </conditionExpression>
            </sequenceFlow>
  • 相关阅读:
    设计模式——单例模式
    设计模式——工厂模式在开发中的应用(简单计算器)
    设计模式——简单工厂模式—工厂方法模式—抽象工厂模式(比较)
    设计模式——抽象工厂模式
    设计模式——工厂方法模式
    设计模式——简单工厂
    Win7使用初体验
    上传文件夹
    java上传文件夹到oss
    java+上传一个文件夹
  • 原文地址:https://www.cnblogs.com/zhlblogs/p/14041899.html
Copyright © 2011-2022 走看看