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());  }

}

												

Activiti-05-.Deployment and MN 2.0 Introduction的更多相关文章

  1. ZOJ2418 Matrix 2017-04-18 21:05 73人阅读 评论(0) 收藏

    Matrix Time Limit: 2 Seconds      Memory Limit: 65536 KB Given an n*n matrix A, whose entries Ai,j a ...

  2. Activiti工作流学习-----基于5.19.0版本(6)

    七. BPMN的简介 读者了解到这里,应付一般的工作流开发已经足够了.此处应该有华丽的分割线,在工作流项目中核心开发人员主要是对工作流业务设计以及实现,而初级开发人员是对业务功能的代码实现.以后将主要 ...

  3. Activiti工作流学习-----基于5.19.0版本(3)

    前面关于eventType的属性值的配置简单的说了一下,activiti支持的值如下表所示:这是我摘抄的activiti官网的 Event 的名字 描述 Event的类名 ENGINE_CREATED ...

  4. Activiti工作流学习-----基于5.19.0版本(5)

    五.与Spring集成 实际项目中一般都有Spring的身影,与Spring集成使得Activiti的实用性得到提高.activiti和Spring整合需要activiti-spring的jar在类路 ...

  5. Activiti工作流学习-----基于5.19.0版本(4)

    四.使用工作流开发 org.activiti.engine.ProcessEngine提供的Service作用在工作流引擎上面,如果所示是模仿一个公司简单的审批流程,你可以下载这个Demo:Activ ...

  6. Activiti工作流学习-----基于5.19.0版本(8)

    8.1.5 Start Event 继续上一篇的事件的分享笔记,Start Event指明该处是流程开始,至于开始事件的类型(消息到达开始,指定的事件循环开始等),定义如何开始是在开始事件圆圈图标里面 ...

  7. Activiti工作流学习-----基于5.19.0版本(7)

    八.BPMN 2.0流程图详解 BPMN 2.0的标准的出现是好事,用户不在被某个工作流开发商绑架或者在工作流中开发妥协,Activiti作为BPMN标准的一套解决方案,使得用户在选择工作流框架时可以 ...

  8. Activiti工作流学习-----基于5.19.0版本(2)

    二.activiti.cfg.xml的其他bean节点配置 2.1 新特性:Job Executor和Async Executor 从5.17.0版本的activiti开始提供作业执行者(Job Ex ...

  9. 1: 介绍Prism5.0 Introduction to the Prism Library 5.0 for WPF(英汉对照版)

     Prism provides guidance designed to help you more easily design and build rich, flexible, and easy- ...

随机推荐

  1. 【学习笔记】深入理解超时调用(setTimeout)和间歇调用(setInterval)

    超时调用(setTimeout):在指定的毫秒数后调用函数或计算表达式. setTimeout(func, 1000); // func执行的函数,1000毫秒 间歇调用(setInterval):按 ...

  2. ORACLE中seq$表更新频繁的分析

    在分析ORACLE的AWR报告时,发现SQL ordered by Executions(记录了按照SQL的执行次数排序的TOP SQL.该排序可以看出监控范围内的SQL执行次数)下有一个SQL语句执 ...

  3. 自动化的基于TypeScript的HTML5游戏开发

    自动化的开发流程 在HTML5游戏开发或者说在Web客户端开发中,对项目代码进行修改之后,一般来说,需要手动刷新浏览器来查看代码修改后运行结果.这种手动的方式费时费力,降低了开发效率.另外,如果我们使 ...

  4. ThinkPHP系统变量,常量,序列化,反序列化,缓存

    变量的输出: 在模板中输出一个变量有两种形式:{$list.name} {$list[‘name’]} 在模板中可以使用系统变量,以$Think.开头 系统变量:(举例选几个) 获得服务器的IP地址: ...

  5. 一个利用pojo类从前端页面request中获取参数的小框架~

    写之前不知道Spring已经实现这样的功能,所以傻傻的写了这个东西! 实现原理挺有趣的在此记录一下.从去年十月参加java开发以来自己终于有了点小进步. 好开心. 解决问题(详解):前端form表单提 ...

  6. CODE大全给你推荐几个免费的leapftp 注册码

    leapftp 2.7.6 注册码, Name: Kmos/CiA in 1999 s/n: MOD1-MO2D-M3OD-NOPQ LeapFTP2.7.5 注册名:swzn 注册码:214065- ...

  7. 深入剖析C++多态、VPTR指针、虚函数表

    在讲多态之前,我们先来说说关于多态的一个基石------类型兼容性原则. 一.背景知识 1.类型兼容性原则 类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代.通过公有继承,派 ...

  8. [2012-06-18]awk利用关联数组合并记录

    问题源起:http://bbs.chinaunix.net/thread-3753784-1-1.html 代码如下 {% capture text %} $awk '{if(!a[$1]){a[$1 ...

  9. C# 反射、与dynamic最佳组合

    在 C# 中反射技术应用广泛,至于什么是反射.........你如果不了解的话,请看下段说明,否则请跳过下段.广告一下:希望我文章的朋友请关注一下我的blog,这也有助于提高本人写作的动力. 反射:当 ...

  10. 通过css控制超链接不显示下划线

    “页面属性”——“链接”——“下划线样式”——“始终无下划线” <style type="text/css"> a:link { text-decoration: no ...