• Activiti-05-.Deployment and MN 2.0 Introduction


    Business archives (业务归档)

     

      为了部署流程,业务档案必须被封装,业务档案是activiti 引擎部署的单元,它相当于zip文件,它包含BPMN 2.0 processes, task forms, rules 和其它文件,可以说是一些资源文件的集合。

    当一个业务归档被部署,它可以扫描扩展名是 .bpmn20.xml或.bpmn

    注意: Java classes present in the business archive will not be added to the classpath. 

    部署方式

    String barFileName = "path/to/process-one.bar";
    ZipInputStream inputStream = new ZipInputStream(new FileInputStream(barFileName));
        
    repositoryService.createDeployment()
        .name("process-one.bar")
        .addZipInputStream(inputStream)
        .deploy();
            

    Deploying with Activiti Explorer

    一个Activiti Explorer web应用允许上传 bar文件和单独的bpmn20.xml文件,选择管理页签点击Deployment

    所有自定义的java类都可以在流程中使用

    Versioning of process definitions 流程定义的版本控制

    对每个流程定义都要完成 属性 key version name id的初始化

    • id  是流程定义的key

    • name 流程定义的名字,并不是必须的
    • 第一次部署有一个特殊的key,分配版本是1.后来的流程定义使用相同的key,版本每次加1,key用来区分流程定义的
    • id属性可以设置为 {processDefinitionKey}:{processDefinitionVersion}:{generated-id}

    为流程中加图片资源

    repositoryService.createDeployment()
     
    .name("expense-process.bar")
     
    .addClasspathResource("org/activiti/expenseProcess.bpmn20.xml")
     
    .addClasspathResource("org/activiti/expenseProcess.png")
     
    .deploy();

    通过api可以再次获取图片资源

      ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                                                             
    .processDefinitionKey("expense")
                                                             
    .singleResult();
     
     
    String diagramResourceName = processDefinition.getDiagramResourceName();
     
    InputStream imageStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);








    如果不想生成流程图,isCreateDiagramOnDeploy 属性可以在流程引擎配置中设置

    <propertyname="createDiagramOnDeploy"value="false"/>

    
    

    Category

    用户自己定义的目标名称空间,而不是使用默认的时:<definitions ... targetNamespace="yourCategory" ...
    
    
    应该按照下面方式部署:
    repositoryService
    .createDeployment()
    .category("yourCategory")
    ...
    .deploy();


    
    

    Defining a process

    1, 创建xml文件,扩展名 是 .bpmn20.xml or .bpmn

    2, 根元素 definitions. 在它里面可以定义多个process。任何一个空的流程定义像下面那样. definitions 元素至少需要 xmlns 和 targetNamespace 声明.targetNamespace可以是任意的, 对于分类管理流程定义很有用

    <definitions 
      xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
      xmlns:activiti="http://activiti.org/bpmn"
      targetNamespace="Examples">
    
      <process id="myProcess" name="My First Process">
        ..
      </process>
    
    </definitions>

    可选的:

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL 
                        http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd

    3, process 元素有两个属性

         id: id是必须的属性,并且以map的key形式放到ProcessDefinition 对象中,id可以用来启动一个流程实例

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess");

        name : 可选属性,一般是给用户看的

    4, 我们通过流程设计器,定义了如下内容的流程定义文件

    <definitions id="definitions"
      targetNamespace="http://activiti.org/bpmn20" 
      xmlns:activiti="http://activiti.org/bpmn"
      xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
            
            <process id="financialReport" name="Monthly financial report reminder process">
              
              <startEvent id="theStart" />
                
              <sequenceFlow id='flow1' sourceRef='theStart' targetRef='writeReportTask' />
                
              <userTask id="writeReportTask" name="Write monthly financial report" >
                <documentation>
                  Write monthly financial report for publication to shareholders.
                </documentation>
                <potentialOwner>
                  <resourceAssignmentExpression>
                    <formalExpression>accountancy</formalExpression>
                  </resourceAssignmentExpression>
                </potentialOwner>
              </userTask>
                
              <sequenceFlow id='flow2' sourceRef='writeReportTask' targetRef='verifyReportTask' />
                  
              <userTask id="verifyReportTask" name="Verify monthly financial report" >
                <documentation>
                  Verify monthly financial report composed by the accountancy department.
                  This financial report is going to be sent to all the company shareholders.  
                </documentation>
                <potentialOwner>
                  <resourceAssignmentExpression>
                    <formalExpression>management</formalExpression>
                  </resourceAssignmentExpression>
                </potentialOwner>
              </userTask>
                
              <sequenceFlow id='flow3' sourceRef='verifyReportTask' targetRef='theEnd' />
                  
              <endEvent id="theEnd" />
                  
            </process>
            
    </definitions>

    5, 有了流程定义文件之后,我们需要部署这个流程定义文件

    Deployment deployment = repositoryService.createDeployment()
     
    .addClasspathResource("FinancialReportProcess.bpmn20.xml")
     
    .deploy();

    6, 部署之后,就可以启动一个流程实例了

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("financialReport"); //这个key就是流程定义中定义的process  的id

    通过start事件后,流程会沿着start事件的所有输出流执行(该例子中
    只有一个流),执行到第一个任务(“编制月度财务报表”)。
    此时Activiti引擎会向持久化数据库中存储一个任务。此时,
    关联在该任务上的用户或组的分配得以解析,并且也被存储到数据库中。
    值得注意的是Activiti引擎会继续流程的执行步
    骤直到流程执行进入一种等待状态,比如用户任务。
    在这样一种等待状态,流程实例的当前状态被存储到数据库中。流
    程会保持该状态直到有用户决定完成其任务。那时,流程引擎会继续执行流程直到流程进入一个新的等待状态或流程终
    点。
    其间,如果遇到流程引擎重启或崩溃的情况,流程状态也是安全的保存在数据库中。

    流程的状态 时刻会在数据库中保存的
    任务创建后,startProcessInstanceByKey 方法就会返回,因为用户任务的活动处于等待状态。该例子中,任务分配给了一
    个组,这意味着该组中的每个成员都是任务执行的候选者

     7, 获取任务列表

    List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("kermit").list();
    注意,我们传递给该方法的用户必须是accountancy组的成员,因为这在流程定义中进行了声明。
    <potentialOwner>
      <resourceAssignmentExpression>
        <formalExpression>accountancy</formalExpression>
      </resourceAssignmentExpression>
    </potentialOwner>
    我们也可以利用这个组名使用任务查询的API得到同样的结果。此时我们可以向代码中添加如下逻辑:
    TaskService taskService = processEngine.getTaskService();
    List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("accountancy").list();

    8, 会计现在需要认领此任务。通过认领任务,将有专人作为该任务的代理人(译注,代理人即为分配到任务的人或责任人),
    同时该任务会从会计组其他成员的任务列表中消失。程序上完成认领任务如下
    taskService.claim(task.getId(),"fozzie");

    该任务现在存在于认领该任务的候选者的个人任务列表中
    List<Task> tasks = taskService.createTaskQuery().taskAssignee("fozzie").list();
    9, 完成任务
    taskService.complete(task.getId());

    10. 是否完成可以在历史中查看
    HistoryService historyService = processEngine.getHistoryService();
    HistoricProcessInstance historicProcessInstance =
    historyService
    .createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();
    System.out.println("Process instance end time: "+ historicProcessInstance.getEndTime());

    代码综述

    public class TenMinuteTutorial{
     
     
    publicstaticvoid main(String[] args){
       
       
    // Create Activiti process engine
       
    ProcessEngine processEngine =ProcessEngineConfiguration
         
    .createStandaloneProcessEngineConfiguration()
         
    .buildProcessEngine();
       
       
    // Get Activiti services
       
    RepositoryService repositoryService = processEngine.getRepositoryService();
       
    RuntimeService runtimeService = processEngine.getRuntimeService();
       
       
    // Deploy the process definition
        repositoryService
    .createDeployment()
         
    .addClasspathResource("FinancialReportProcess.bpmn20.xml")
         
    .deploy();
       
       
    // Start a process instance
       
    String procId = runtimeService.startProcessInstanceByKey("financialReport").getId();
       
       
    // Get the first task
       
    TaskService taskService = processEngine.getTaskService();
       
    List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("accountancy").list();
       
    for(Task task : tasks){
         
    System.out.println("Following task is available for accountancy group: "+ task.getName());
         
         
    // claim it
          taskService
    .claim(task.getId(),"fozzie");
       
    }
       
       
    // Verify Fozzie can now retrieve the task
        tasks
    = taskService.createTaskQuery().taskAssignee("fozzie").list();
       
    for(Task task : tasks){
         
    System.out.println("Task for fozzie: "+ task.getName());
         
         
    // Complete the task
          taskService
    .complete(task.getId());
       
    }
       
       
    System.out.println("Number of tasks for fozzie: "
               
    + taskService.createTaskQuery().taskAssignee("fozzie").count());
       
       
    // Retrieve and claim the second task
        tasks
    = taskService.createTaskQuery().taskCandidateGroup("management").list();
       
    for(Task task : tasks){
         
    System.out.println("Following task is available for accountancy group: "+ task.getName());
          taskService
    .claim(task.getId(),"kermit");
       
    }
       
       
    // Completing the second task ends the process
       
    for(Task task : tasks){
          taskService
    .complete(task.getId());
       
    }
       
       
    // verify that the process is actually finished
       
    HistoryService historyService = processEngine.getHistoryService();
       
    HistoricProcessInstance historicProcessInstance =
          historyService
    .createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();
       
    System.out.println("Process instance end time: "+ historicProcessInstance.getEndTime());
     
    }

    }

    
    
    ----------- 赠人玫瑰,手有余香     如果本文对您有所帮助,动动手指扫一扫哟   么么哒 -----------


    未经作者 https://www.cnblogs.com/xin1006/ 梦相随1006 同意,不得擅自转载本文,否则后果自负
  • 相关阅读:
    sklearn的train_test_split函数
    Tensorflow报错:InvalidArgumentError: You must feed a value for placeholder tensor 'input_y' with dtype
    conda install 安装太慢怎么办?
    python merge、concat合并数据集
    如何调用写好的指定模块?——sys.path
    对分类特征做编码
    ThreadPoolExecutor的创建
    MYSQL中VARCHAR长度怎么选?
    JAVA实现一个低性能的WEB服务器(一)——线程池
    在连接校园网的同时连接外网|同时访问内网与外网
  • 原文地址:https://www.cnblogs.com/xin1006/p/3407971.html
Copyright © 2020-2023  润新知