Activiti笔记——学习的一个过程

64人阅读 评论(0) 收藏 举报
分类:

1 什么是工作流?

 

工作流(Workflow),就是通过计算机对业务流程自动化执行管理。实现多个参与者共同完成一个业务流程,使用业务流程自动化去执行。

 

什么工作流系统?

具有工作流功能的系统叫做工作流系统,如果具有工作流功能,如果流程变化只需要修改流程,而不需要修改业务功能。

 

了解工作流系统应用行业及具体应用场景:

消费品行业,制造业,电信服务业,银证险等金融服务业,物流服务业,物业服务业,物业管理,大中型进出口贸易公司,政府事业机构,研究院所及教育服务业等,特别是大的跨国企业和集团公司


 

什么是activiti

 

Activiti是一个工作流引擎,引擎需要嵌入到业务系统中才可以发挥作用。通过activiti实现工作流。

将业务流程抽取成一个流程定义,流程定义按照bpmn2.0标准进行定义,activiti就会按照讲预先定义好的流程进行流程的执行,从而实现流程的自动化管理,减少系统开发由业务流程变更增加的成本。

 

Activiti是前身就是jbpm4(也是一个工作流引擎),Activiti中的apiservice接口和jbpm4很相似。

 

2.1 术语

l BPM

 

BPMBusiness Process Management,即业务流程管理,是一种以规范化的构造端到端的卓越业务流程为中心,以持续的提高组织业务绩效为目的的系统化方法,常见商业管理教育如EMBAMBA等均将BPM包含在内。

最早在企业提出进行业务流程管理。企业中对业务流程进行管理优化,减少企业成本。

 

l Bpm软件

实现了业务流程管理的软件,相当于上边说的工作流系统。

 

l Bpmn2.0(掌握)

Bpmn2.0和上边的bpm是不同的概念!!!

 

BPMNBusiness Process Model And Notation- 业务流程模型和符号,是由BPMIBusiness Process Management Initiative)开发的一套标准的业务流程建模符号,使用BPMN提供的符号可以创建业务流程。

 

Activiti是基于bpmn2.0标准进行流程定义,activiti在进行流程定义时,使用这些模型和符号绘制流程图。

 

Event 用一个圆圈表示,它是流程中运行过程中发生的事情。


活动用圆角矩形表示,一个流程由一个活动或多个活动组成


 

一个bpmn图形的例子:

 

Activiti如何使用?

 

Activiti是一个工作流引擎,通常情况下activiti需要嵌入到业务系统中运行。

 

3.1 第一步:部署activiti

工具准备时的注意事项

 

Activiti运行需要在工程中加入jar包:

 Activiti本身的jar

 Activitispring的整合jar

  依赖jar

 

创建数据库(存储流程运行的数据)。

 

3.2 第二步:使用activiti流程建模工具(activity-designer)定义业务流程(.bpmn文件)

Activiti官方提供了一个和eclipse集成插件(activity-designer),用来画流程图,使用bpmn2.0标准(定义模型和符号),画流程图过程就是流程定义的过程。

在线下画流程图。

 

使用Activiti视图

 

 

3.3 第三步:向activiti部署业务流程定义(.bpmn文件)

.bpmn文件(流程定义文件),让activiti识别,让activiti按照流程定义文件的内容去管理业务流程。

.bpmn文件部署到activiti的数据库中,流程定义完成了。

 

 

3.4 第四步:启动一个流程实例

流程定义完成后,如果有参者来发起一个流程,activiti可以按照.bpmn文件内容去管理流程。

比如:张三创建一个采购单表示发起了一个采购流程。李四创建一个采购单,李四也发起一个采购流程。

流程定义和流程实例关系:静态和动态,类似java类和java对象。

 

3.5 第五步:查询待办任务

 

因为现在系统的业务流程已经交给activiti管理,通过activiti就可以查询当前流程执行到哪了,当前用户需要办理什么任务了,这些activiti帮我们管理了,而不像上边需要我们在sql语句中的where条件中指定当前查询的状态值是多少。

 

3.6 第六步:办理任务

当前流程运行到哪了这是由activiti自动管理的,当前参与者就可以完成/办理属于他的当前任务

 

3.7 第七步:流程结束

当任务办理完成没有下一个任务/结点了,这个流程实例就完成了。


关于环境

 

第一个环境:没有加入工作流采购系统

作用:主要学习业务流程和SSH+Activiti

 

第二个环境:activiti测试环境

作用:用于测试activitiapi,提供各种service接口。

需要创建一个数据库:

仅仅有activiti的数据表

 

第三个环境:activiti应用环境,加入工作流的采购系统

需要创建一个数据库:

包括activiti的数据表和业务表(采购系统的表)

 

activiti测试环境

 

Activiti自身环境包括:activitijar包和数据库

 

5.1 activitijar

Activiti下载地址:http://activiti.org/download.html 

 

下载activiti5.14版本,

 

解压:

 

1) Database

activiti运行需要有数据库的支持,支持的数据库有:h2, mysql, oracle, postgres, mssql, db2等,该目录存放activiti的建表脚本。

 

2) Docs

Activiti的帮助文档。

参考

 

中文的说明文档(activiti各各apiservice

 

3) Libs

Activiti所需要的jar

 

源码:

 

核心包:

activiti-engine-5.14.jar

spring整合包:

activiti-spring-5.14.jar

 

4) Wars

官方自带的示例工程。

 

5.2 Activiti Designer流程设计器

用于进行流程定义,按照bpmn2.0标准画流程图。

 

eclipse-juno版本中安装activiti designer设计器:

参数文档开发工具目录下的activiti开发环境配置.docx”中“eclipse插件安装”,其中包括了Activiti插件。

 

流程图画好后,生成一个.bpmn的文件(内容遵循bpmn2.0标准),通过插件可以同时生成一个png图片(流程图)。

 

Activiti的设计器插件安装后:

 

打开菜单Windows->Preferences->Activiti->Save下流程图片的生成方式:

 

5.3 Activiti的数据库


本教程使用mysql数据库

 

使用mysql5.1版本。

 

5.3.1 创建一个用于activiti测试的数据库

 

 

5.3.2 创建数据库表

 

方式1:从下载activiti5.14目录/database中执行sql脚本

 

方法2:通过java程序

 

 

5.4 通过java程序创建数据库

创建数据库思路:

Activiti运行需要核心门面接口ProcessEngine,在创建processEngine时自动检查数据库环境,可以通过数据库操作策略操作数据库。

 

5.4.1 第一步:创建一个java 工程

这是第二个环境,测试activiti

 

5.4.2 第二步:加入jar

 

上边是activiti单独运行的jar

下边是activitispring整合的jar,比上边目录多了springjar包:txspringmvc。。。

 

使用activitispring整合的jar

 

5.4.3 第三步:log4j.properties

 

5.4.4 第四步:activiti.cfg.xml

 

Activiti的全局配置文件,是spring的配置文件。

 

如果和spring没有整合时,配置数据源processEngineConfiguration

数据源:使用dbcp第三方连接池

processEngineConfiguration:用于创建processEngine

 

Activiti通过spring容器在创建processEngineConfiguration

 

数据库操作策略:

 

false(默认):检查数据库表的版本和依赖库的版本, 如果版本不匹配就抛出异常。

true: 构建流程引擎时,执行检查,如果需要就执行更新。 如果表不存在,就创建。

create-drop: 构建流程引擎时创建数据库表, 关闭流程引擎时删除这些表。

drop-create:先删除表再创建表。

create: 构建流程引擎时创建数据库表, 关闭流程引擎时删除这些表。

 

5.4.5 第五步:编写java程序

 

创建一个processEngineConfiguration对象

通过processEngineConfiguration创建procesEngine对象,同时自动创建数据库表。

 

5.4.6 数据库创建完成,

 

23张表:

 

 

5.4.7 表的命名规则

 

Activiti的服务架构

 

6.1 架构图

 

 

根据activiti.cfg.xml创建processEngineConfiguration

通过processEngineConfiguration创建ProcessEngine

通过ProcessEngine调用getXXXXService文件得到各各Service

 

回顾:

1. 什么是工作流

2. Activiti是什么?

3. 如何使用工作流

4. 什么是BPM?什么是BPMN?

5. 操作步骤?

6. 体系结构?

6.2 Activiti.cfg.xml

 

6.2.1 Activiti单独运行:

activiti.cfg.xmlactiviti的核心配置文件,名称不固定。

在此文件中配置processEngineConfiguration,通过processEngineConfiguration创建processEngine

 

Activiti单独运行通过StandaloneProcessEngineConfiguration创建processEngine

 

<!-- processEngineConfiguration: 用于创建processEngine -->

<bean id="processEngineConfiguration"

class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

<!-- 数据源 -->

<property name="dataSource" ref="dataSource" />

<!-- activiti数据库表处理策略 -->

<property name="databaseSchemaUpdate" value="drop-create" />

</bean>

 

6.2.2 Activitispring整合

创建applicationContext-activiti.xml,在此文件配置activiti组件。

 

使用SpringProcessEngineConfigurationactivitispring整合。

 

配置:processEngineConfiguration

 

<!-- 工作流引擎配置bean -->

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">

<!-- 数据源 -->

<property name="dataSource" ref="dataSource" />

<!-- 使用spring事务管理器 -->

<property name="transactionManager" ref="transactionManager" />

<!-- 数据库策略 -->

<property name="databaseSchemaUpdate" value="drop-create" />

<!-- activiti的定时任务关闭 -->

<property name="jobExecutorActivate" value="false" />

 

</bean>

 

 

在此文件中配置processEngine

<!-- 流程引擎 -->

<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">

<property name="processEngineConfiguration" ref="processEngineConfiguration" />

</bean>

 

配置service;

 

<!-- 资源服务service -->

<bean id="repositoryService" factory-bean="processEngine"

factory-method="getRepositoryService" />

<!-- 流程运行service -->

<bean id="runtimeService" factory-bean="processEngine"

factory-method="getRuntimeService" />

<!-- 任务管理service -->

<bean id="taskService" factory-bean="processEngine"

factory-method="getTaskService" />

<!-- 历史管理service -->

<bean id="historyService" factory-bean="processEngine"

factory-method="getHistoryService" />

<!-- 用户管理service -->

<bean id="identityService" factory-bean="processEngine"

factory-method="getIdentityService" />

<!-- 引擎管理service -->

<bean id="managementService" factory-bean="processEngine"

factory-method="getManagementService" />

 

 

6.3 ProcessEngine

 

相当于一个门面接口,通过ProcessEngineConfiguration创建processEngine,通过ProcessEngine创建各各service接口。

门面是一个设计模式,定义一个简单bean,定义属性(门面包括组件java对象),定义get/set方法,调用门面get方法获取组件。

 

创建方式1;

 

ProcessEngine processEngine = ProcessEngineConfiguration

.createProcessEngineConfigurationFromResource(resource).buildProcessEngine();

 

创建方式2

 

6.4 service

 

 

RepositoryService

activiti的资源管理类,部署流程定义、查询流程定义、删除流程定义、查看流程定义文件(.bpmn.png

RuntimeService

activiti的流程运行管理类,启动一个流程实例,查询当前运行流程

TaskService

activiti的任务管理类,查询当前待办任务,办理当前的任务

HistoryService

activiti的历史管理类,查询历史流程信息、查询历史任务信息

IdentityService

activiti的用户身份管理类,用户授权(用户信息、组信息、用户与组关系信息)

FormService

activiti的表单管理类,在流程图中配置表单数据

ManagerService

activiti的引擎管理类,监控activiti运行状态,通常用超级管理员使用

 

注:红色标注为常用service

 

通过调用ProcessEngine.getXXXService()方法:

 

RepositoryService repositoryService = processEngine.getRepositoryService ()

RuntimeService runtimeService = processEngine.getRuntimeService();

…..

 

activiti入门体验

 

7.1 需求:

员工创建采购单,经过部门经理、总经理、财务三级审核。业务流程图如下:

7.2 流程定义:

 

使用流程设计器,定义流程,生成.bpmn文件、.png文件。

打开properties视图,


流程定义的key

 

流程定义key用于标识符一个业务流程,针对相同的业务流程key是相同的,比如两个采购流程,由于前后修改采购流程不一样,key定义为一样,因为它就是一个采购流程。

 

创建采购单结点:

 

指定任务的办理人:


assignee中设置任务办理人。对每个userTask结点都设置assignee

 

自动生成流程定义文件:.bpmn,.png

 

7.3 部署流程定义

流程修改后,一定要重新部署流程!!!!!

 

将流程定义文件部署到activiti的数据库中。

使用RepositoryService进行流程定义部署。


7.4 启动流程实例

 

由参与者发起一个流程,使用runTimeService


7.5 查询待办任务

用户查询当前自己需要办理的任务。

使用TaskService查询当前待办任务。

 

7.6 办理任务

 

使用TaskService完成任务

 

流程定义

 

8.1 操作流程:

1、 用户在线下定义bpmn

生成bpmn文件,png不是必须要生成的,在web页面上提供一个功能查询流程定义图这个功能,activiti本身也能生成png,生成图片会中文乱码,图中结点坐标位置错乱,要提前通过eclipse插件生成png文件。

需要两个文件:.bpmn.png

2、 通过repositoryService对流程定义进行部署

 

8.2 部署方法

 

8.2.1 单个文件部署

.bpmn.png两个文件部署到activiti

 

代码:

数据库操作

 

向流程部署表写一条记录

SELECT * FROM act_re_deployment #流程部署表

 

向流程定义表写记录,如果一次部署多个流程需要写多条记录。

SELECT * FROM act_re_procdef #流程定义表

 

Id_ 流程定义id:流程定义key:版本号:流水号

Version_ 流程定义版本:流程定义key,版本号自动加1

Key_ 流程定义key:用于标识一个业务流程,不管版本是否改变,相同的业务流程使用相同的key

deployment_id_ 流程部署id

RESOURCE_NAME_ bpmn文件名称:

DGRM_RESOURCE_NAME_ png文件名称

 

bpmnpng写到资源表:

SELECT * FROM act_ge_bytearray #资源表

 

注意:流程部署表和流程定义表是一对多关系。建议一次部署只部署一个流程,方便管理。

 

建议使用单个文件部署部署。

 

8.2.2 压缩包部署

.bpmn.png两个文件压缩成zip文件,通过repositoryService进行部署

 

 

通过代码部署zip文件;

 

@Test

public void deployProcessByZip() {

// 定义zip输入流

InputStream inputStream = this

.getClass()

.getClassLoader()

.getResourceAsStream(

"cn/itcast/activiti/first/diagram/purchasing/purchasingflow01.zip");

ZipInputStream zipInputStream = new ZipInputStream(inputStream);

// 获取repositoryService

RepositoryService repositoryService = processEngine

.getRepositoryService();

// 流程部署

Deployment deployment = repositoryService.createDeployment()//

.addZipInputStream(zipInputStream)//

.deploy();

System.out.println("流程部署id" + deployment.getId());

System.out.println("流程部署名称:" + deployment.getName());

}

 

8.3 流程定义查询

 

通过此功能查询本系统通过actviti管理的流程有哪些。

 

使用repositoryService查询流程定义,可以根据流程定义的key查询某个业务流程在activiti中的流程定义。

 

// 流程定义的查询

@Test

public void queryProcessDefinition() {

//流程定义的key

String processDefinitionKey = "purchasingflow";

// 使用repositoryService

RepositoryService repositoryService = processEngine

.getRepositoryService();

//流程定义查询对象

ProcessDefinitionQuery processDefinitionQuery = repositoryService

.createProcessDefinitionQuery();

//设置查询条件

processDefinitionQuery.processDefinitionKey(processDefinitionKey);

//得出查询列表

List<ProcessDefinition> list =  processDefinitionQuery.list();

for(ProcessDefinition processDefinition:list){

System.out.println("--------------------------------");

System.out.println("流程定义的id"+processDefinition.getId());

System.out.println("流程定义的名称:"+processDefinition.getName());

System.out.println("流程定义的key"+processDefinition.getKey());

System.out.println("流程部署id"+processDefinition.getDeploymentId());

System.out.println("bpmn文件名:"+processDefinition.getResourceName());

System.out.println("png文件名:"+processDefinition.getDiagramResourceName());

}

 

}

 

8.4 流程定义的资源文件查询

 

需求:查看activiti中流程定义的资源文件(.bpmn.png),程序员需要查看bpmnxml格式),终端用户查询图片。

 

使用repositoryService


// 流程定义资源文件查看

@Test

public void getProcessResources() throws IOException {

 

// 使用repositoryService

RepositoryService repositoryService = processEngine

.getRepositoryService();

 

// 流程定义id

String processDefinitionId = "purchasingflow:3:1104";

// 查询一个流程定义

 

ProcessDefinition processDefinition = repositoryService

.createProcessDefinitionQuery()

.processDefinitionId(processDefinitionId).singleResult();

 

String bpmn_name = processDefinition.getResourceName();

 

String png_name = processDefinition.getDiagramResourceName();

 

// 部署id,来源于流程部署表

String deploymentId = processDefinition.getDeploymentId();

 

// 资源文件名称

String resourceName_bpmn = bpmn_name;

String resourceName_png = png_name;

 

//bmpn的输入流

InputStream inputStream_bpmn = repositoryService.getResourceAsStream(deploymentId, resourceName_bpmn);

//png的输入流

InputStream inputStream_png = repositoryService.getResourceAsStream(deploymentId, resourceName_png);

//将输入流通过文件输出流写到磁盘

FileOutputStream fileOutputStream_bpmn = new FileOutputStream(new File("D:/purchasingflow.bpmn"));

FileOutputStream fileOutputStream_png = new FileOutputStream(new File("D:/purchasingflow.png"));

byte[] b = new byte[1024];

int len=-1;

while((len=inputStream_bpmn.read(b, 0, 1024))!=-1){

fileOutputStream_bpmn.write(b, 0, len);

}

while((len=inputStream_png.read(b, 0, 1024))!=-1){

fileOutputStream_png.write(b, 0, len);

}

//释放资源

inputStream_bpmn.close();

inputStream_png.close();

fileOutputStream_bpmn.close();

fileOutputStream_png.close();

}

 

8.5 流程定义删除

使用repositoryService删除

流程一但启动是不删除的,给超级管理开放级联的功能。可以暂停/激活流程的执行。

Activiti应用(部署流程定义)

流程定义变量

@Test

   public void testVariable(){

   String processDefinitionKey = ResourceBundle.getBundle("bpmnkey").getString("processDefinitionKey");

   RuntimeService runtimeService = pe.getRuntimeService();

   

   Map<String ,Object> variables = new HashMap<String,Object>();

   variables.put("time", "明天请假");

   variables.put("address", "去医院");

   variables.put("reason","因为生病了" );

   variables.put("day", 8);

   variables.put("startDay", new Date());

   

   Person person = new Person();

   person.setId(1);

   person.setName("abc");

   person.setBirthday(new Date());

   variables.put("person",person);

   runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);

   }

   

   @Test

   public void testGetVariable(){

   String processDefinitionKey = ResourceBundle.getBundle("bpmnkey").getString("processDefinitionKey");

   TaskService taskService = pe.getTaskService();

   Task task = taskService.createTaskQuery()

      .processDefinitionKey(processDefinitionKey)

      .taskAssignee("张三")

      .singleResult();

   System.out.println(taskService.getVariable(task.getId(), "reason"));

   Date startTime = (Date)taskService.getVariable(task.getId(), "startDay");

   System.out.println(startTime.toLocaleString());

   

   Person p = (Person) taskService.getVariable(task.getId(), "person");

   System.out.println(p);

   }

 

历史记录的查看

@Test

    public void testHistoric(){

    HistoryService historyService = pe.getHistoryService();

    HistoricProcessInstanceQuery hpiq = historyService.createHistoricProcessInstanceQuery();

    String processDefinitionKey = ResourceBundle.getBundle("bpmnkey").getString("processDefinitionKey");

    hpiq.processDefinitionKey(processDefinitionKey);

    List<HistoricProcessInstance> list = hpiq.list();

    for(HistoricProcessInstance hiProcessInstance :list){

    System.out.println(hiProcessInstance.getProcessDefinitionId());

    System.out.println(hiProcessInstance.getId());

    }

    }

    

    @Test

    public void testHistoric01(){

    HistoryService historyService = pe.getHistoryService();

    HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery();

    query.processInstanceId("1501");

    

    List<HistoricActivityInstance> list = query.list();

    for(HistoricActivityInstance ai :list){

    System.out.println(ai.getActivityId());

    System.out.println(ai.getActivityName());

    System.out.println(ai.getProcessDefinitionId());

    System.out.println(ai.getProcessInstanceId());

    System.out.println("==============================");

    }

    }

查看评论

activiti工作流学习总结

开篇先说 此为 一个初次接触工作流的小白,怀着忐忑的心情写下的,写给自己,也写给他人,很多东西我不是很明白,内心。。。, 因为我的整个学习路线就是看各种有关activiti的博客,单元测试, ,...
  • qq_34250793
  • qq_34250793
  • 2017-06-17 16:28:49
  • 934

Activiti工作流框架学习笔记(一)

工作流的概念先看下面两张图: 对以上两张图进行说明: 假设这两张图就是华谊兄弟的请假流程图 图的组成部分: 人物:范冰冰、冯小刚、王中军 事件(动作):请假、批准、不批准 通过以上分析我们就可...
  • yerenyuan_pku
  • yerenyuan_pku
  • 2017-05-07 00:52:58
  • 7967

activiti笔记

  • 2013年11月29日 09:56
  • 2.66MB
  • 下载

工作流Activiti的学习总结(六)Antiviti的安装详细过程

activiti-5.6的安装        项目中采用最新的Activiti版本为5.6GA的activiti REST方式访问相关的REST WebService服务,activiti提供了 ...
  • qq_31387691
  • qq_31387691
  • 2016-08-29 14:52:14
  • 1007

传智播客 activiti 视频资料 第1天 共4天

  • 2017年10月31日 10:42
  • 489.73MB
  • 下载

Activiti 学习笔记 小结

/**更新请假状态,启动流程实例,让启动的流程实例关联业务*/ @Override public void saveStartProcess(WorkflowBean workflow...
  • xunzaosiyecao
  • xunzaosiyecao
  • 2016-09-16 15:35:44
  • 2784

RIP学习笔记

小型网络比较适用静态路由技术 大中型网络一般采用动态路由协议 基于运行特征分类 距离矢量协议  RIP EIGRP BGP 链路状态协议  OSPF ISIS 基于运行范围 IGP(内部网关协...
  • samtaoys
  • samtaoys
  • 2016-10-16 11:06:37
  • 501

Activiti简单学习心得一

前言: 在做项目的时候,公司的项目要用到Activiti,所以,我就开始了各种资料的搜寻,包括视频,代码,源码等等等等,都尝试了一遍,但是还是感觉学不好。有一本书还挺不错的,推荐给大家,这一系列的书...
  • u012225679
  • u012225679
  • 2017-06-06 18:07:37
  • 176

Activiti工作流学习总结

一、工作流的初步认识 在我初步学习完工作流的理解中,工作流就是将开发中由代码控制的业务流程状态抽取出来然后进行统一控制的机制!比如在实际开发中,我们需要表明一个状态的改变,可以通过字段status来进...
  • eininotop
  • eininotop
  • 2017-09-23 21:08:26
  • 385

传智播客activiti视频+源代码+资料

  • 2018年02月01日 16:06
  • 49B
  • 下载
    个人资料
    等级:
    访问量: 5431
    积分: 718
    排名: 7万+
    文章存档