zoukankan      html  css  js  c++  java
  • Activiti流程定义语言

    1、流程(process)

      bpmn文件一个流程的根元素。一个流程就代表一个工作流。

    2、顺序流(sequenceFlow)

      顺序流是连接两个流程节点的连线,代表一个节点的出口。流程执行完一个节点后,会沿着节点的所有外出顺序流继续执行。 就是说,BPMN 2.0默认的行为就是并发的: 两个外出顺序流会创造两个单独的,并发流程分支。

      顺序流主要由4个属性组成:

        Id: 唯一标示,用来区分不同的顺序流

        sourceRef:连线的源头节点ID

        targetRef:连线的目标节点ID

        name(可选):连线的名称,不涉及业务,主要用于显示

          说明:

          1)     结束节点没有出口

          2)     其他节点有一个或多个出口。如果有一个出口,则代表是一个单线流程;如果有多个出口,则代表是开启并发流程。

    3、节点

      1、开始事件节点(startEvent)

        开始事件用来指明流程在哪里开始。开始事件的类型(流程在接收事件时启动, 还是在指定时间启动,等等),定义了流程如何启动, 这通过事件中不同的小图表来展示。 在XML中,这些类型是通过声明不同的子元素来区分的。

        1)空开始事件

          空开始事件技术上意味着没有指定启动流程实例的触发条件。最常用的一种开始,意味着流程的启动需要手动触发,通过调用api的startProcessInstanceByXXX方法。注意: 子流程都有一个空开始事件。

          ProcessInstanceprocessInstance =runtimeService.startProcessInstanceByXXX();

          图形标记:空开始事件显示成一个圆圈,没有内部图表(没有触发类型)

          XML结构如下:<startEventid="start"name="my start event"/>

        2)定时开始事件

          定时开始事件用来在指定的时间创建流程实例。 它可以同时用于只启动一次的流程 和应该在特定时间间隔启动多次的流程。

          注意:

            1.子流程不能使用定时开始事件。

            2.定时开始事件在流程发布后就会开始计算时间。 不需要调用     startProcessInstanceByXXX,虽然也而已调用启动流程的方法, 但是   那会导致调用            startProcessInstanceByXXX时启动过多的流程。

            3.当包含定时开始事件的新版本流程部署时, 对应的上一个定时器就会    被删除。这是因为通常不希望自动启动旧版本流程的流程实例。

          图形标记:定时开始事件显示为一个圆圈,内部是一个表。

          XML内容:

            定时开始事件的XML内容是普通开始事件的声明,包含一个定时定义子元素。

            示例:流程会启动4次,每次间隔5分钟,从2013年9月18日,12:10开始计时。

     <startEvent id="theStart">
         <timerEventDefinition>                
            <timeCycle>R4/2013-09-18T12:13/PT5M</timeCycle>                     
        </timerEventDefinition>
     </startEvent>   

            示例:流程会根据选中的时间启动一次。

     <startEventid="theStart">            
        <timerEventDefinition>                
            <timeDate>2013-10-31T23:59:24</timeDate>            
        </timerEventDefinition>        
     </startEvent>     

      2、结束事件节点(endEvent)

        结束事件表示(子)流程(分支)的结束。 结束事件都是触发事件。 这是说当流程达到结束事件,会触发一个结果。 结果的类型是通过事件的内部黑色图标表示的。

        1)空结束事件

          空结束事件意味着到达事件时不会指定抛出的结果。 这样,引擎会直接结束当前执行的分支,不会做其他事情。

          图形标记:空结束事件是一个粗边圆圈,内部没有小图表(无结果类型)

          XML内容:<endEvent id="end" name="my end event"/>

          空结束事件的XML内容是普通结束事件定义,不包含子元素 (其他结束事件类型都会包含声明类型的子元素)。

      3、任务节点 (Task)

        1)接收任务节点(receiveTask)

          接收任务是一个简单任务,它会等待对应消息的到达。 当前,官方只实现了这个任务的java语义。 当流程达到接收任务,流程状态会保存到数据库中。

          在任务创建后,意味着流程会进入等待状态, 直到引擎接收了一个特定的消息, 这会触发流程穿过接收任务继续执行。

          图形标记:接收任务显示为一个任务(圆角矩形),右上角有一个消息小标记。 消息是白色的(黑色图标表示发送语义)

          XML内容:<receiveTask id="waitState" name="wait"/>  

          当前任务(一般指机器自动完成,但需要耗费一定时间的工作)完成后,向后推移流程,可以调用runtimeService.signal(executionId),传递接收任务上流程的id。

          演示代码如下:

    ProcessInstance pi =runtimeService.startProcessInstanceByKey("receiveTask");
    Execution execution=runtimeService.createExecutionQuery() 
                                       .processInstanceId(pi.getId())
                         .activityId(
    "waitState")
                         .singleResult(); assertNotNull(execution); runtimeService.signal(execution.getId());

        2)用户任务节点 (userTask)

          用户任务用来设置必须由人员完成的工作。 当流程执行到用户任务,会创建一个新任务, 并把这个新任务加入到分配人或群组的任务列表中。

           图形标记:用户任务显示成一个普通任务(圆角矩形),左上角有一个小用户图标。

          XML内容XML中的用户任务定义如下。id属性是必须的。 name属性是可选的。

          <userTask id="theTask" name="Important task"/>

          用户任务也可以设置描述(实际上所有BPMN 2.0元素都可以设置描述)。 添加documentation元素可以定义描述。

    <userTask id="theTask" name="Schedule meeting">  
    <documentation>
              Schedule an engineering meeting for next week with the new hire.  
    </documentation>

          在实际应用中,用户接到任务后可以参照任务描述来办理任务,描述文本可以通过标准的java方法来获得:task.getDescription()

          任务分配

          用户任务的办理都需要人工的参与。用户任务可以分为两大类。私有任务和公有任务(可接任务)。

            私有任务

            私有任务即有直接分配给指定用户的任务。只有一个用户可以成为任务     的执行者。 在activiti中,用户叫做执行者。 拥有执行者的用户任务  (即私有任务)对其他用户是不可见的。只能出现执行者的个人任务列表中.

            直接把用户任务分配给指定用户使用assignee属性,XML代码如下:

            <userTask id="theTask" name="my task" activiti:assignee="sirius"/>

            Assignee属性对应的值为一个用户的ID。

            直接分配给用户的任务可以通过TaskService像下面这样办理:

    List<Task>tasks =taskService.createTaskQuery().taskAssignee("sirius").list();
    
    Task task = tasks.get(0);// 假设任务集合的第一条是要办理的任务
    
    taskService.complete(task.getId());

            公有任务

              有的用户任务在指派时无法确定具体的办理者,这时任务也可以加入到     人员的候选任务列表中,然后让这些人员选择性认领和办理任务。

              公有任务的分配可以分为指定候选用户和候选组两种。

                a) 把任务添加到一批用户的候选任务列表中,使用candidateUsers     属   性,XML内容如下:

                  <userTaskid="theTask"name="my task"activiti:candidateUsers="sirius,kermit"/>

                  candidateUsers属性内为用户的ID,多个用户ID之间使用(半角)逗 号间隔。

                b)  把任务添加到一个或多个候选组下,这时任务对组下的所有用户可      见,首先得保证每个组下面有用户,通过IdentityService对象创建用户   和组,然后把用户添加到对应的组下。

               然后配置组任务,使用candidateGroups属性,XML内容如下:

              <userTask  id="theTask"   name="my task"     activiti:candidateGroups="testGroup,developGroup"/>

              间接分配给用户的任务,可以通过TaskService像下面这样操作:

    List<Task>tasks =taskService.createTaskQuery()
    
                                      .taskCandidateUser("sirius").list();
    
    Task task = tasks.get(0);// 假设任务集合的第一条是要办理的任务
    
    String taskId = task.getId();
    
    taskService.claim(taskId ,“sirius”); //认领任务,让用户成为任务的执行者
    
    taskService.complete(taskId );

                说明:

                  1.要维护用户和组得使用用户管理服务对象,使用       processEngine  得到IdentityService。

                  2.要分配组任务必须先创建组,而且组下得有用户,用户和组的     最关键属性是ID。

                  3.使用newUser(userId)和newGroup(groupId)创建用户  和组。

                  4.使用createMembership(userId,groupId)把用户挂到  组下。

                  5.办理候选任务,首先得认领任务,让用户成为任务的执行者。

                如果上面的方式还不够灵活,那么我们也可以自定义一个任务分配处理器,通过代码的方式来动态设置任务的属性。XML代码如下:

    <userTask id="task1" name="My task"> 
        <extensionElements>    
    <activiti:taskListener event="create" class="org.activiti.MyAssignmentHandler"/>  
        </extensionElements>
    </userTask>

                DelegateTask会传递给TaskListener的实现, 通过它可以设置执行人,候选人和候选组:

    Public class MyAssignmentHandler implements TaskListener {
      
        Public void notify(DelegateTask delegateTask){ 
        // 执行用户搜索相关代码    
        ...
        // 然后把获取到的用户通过下面方法,设置给当前触发事件的任务
            delegateTask.setAssignee("sirius");
            //delegateTask.addCandidateUser("kermit");
           //delegateTask.addCandidateGroup("testGroup"); 
           ...  
    }
    }

           上述两个虽然都可以统称为任务节点,但是还是有本质区别:

              1.receiveTask主要代表机器自动执行的,userTask代表人工干预的。

              2.receiveTask任务产生后会在act_ru_execution表中新增一条记录,  而userTask产生后会在act_ru_execution和act_ru_task(主要记录任   务的发布时间,办理人等信息)中各产生一条记录。

              3.receiveTask任务提交方式使用RuntimeService的signal方法提交,  userTask任务提交方式使用TaskService的complete方法提交。

     

        

  • 相关阅读:
    小程序ArrayBuffer转JSON
    梅林路由修改hosts
    小程序半屏弹窗(Half Screen Dialog)插槽(Slot)无效的解决方法
    [小程序]存在将未绑定在 WXML 的变量传入 setData 的解决方法!
    小程序scroll-view指定高度
    修改小程序mp-halfScreenDialog组件高度
    小程序图片懒加载组件 mina-lazy-image
    OpenCOLLADA v1.6.68 MAYA MAX 全文件
    位运算相关知识
    全排列 next_permutation() 函数
  • 原文地址:https://www.cnblogs.com/cxyj/p/3878121.html
Copyright © 2011-2022 走看看