Activiti教程

  1. 工作流概念

工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。

工作流管理系统(Workflow Management System, WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。

 

  1. Activiti简单介绍

Activiti5是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss jBPM的项目架构师,它特色是提供了eclipse插件,开发人员可以通过插件直接绘画出业务流程图。

  1. activiti是一个工作流引擎,Activiti工作的核心,负责生成流程运行时的各种实例及数据、监控和管理流程的运行。
  1. 在IDEA安装acti插件

01823883feb373b6bdbf703552e36e62f97.jpg

 

c1520462ba4151e5b843307c51765a51254.jpg

  1. 了解activiti的目录结构
  1. 目录结构看名字也就知道什么意思

d34279c331cadf91143a080fa642a21481d.jpg

  1. 工作流框架底层需要有数据库支持,activiti5.13版本对应23张表,activiti框架底层使用mybatis操作数据库。
  2. JBPM也是一个工作流框架,JBPM4.4底层18张表,底层使用hibernate操作数据库。

 

  1. BPMN

业务流程建模与标注(Business Process Model and Notation,BPMN) ,描述流程的基本符号,包括这些图元如何组合成一个业务流程图(Business Process Diagram)

 

  1. activiti的入门教程
    1. 导入activiti所需要的数据表
  1. 这里使用mysql,所以导入database文件夹下面三个sql文件
  2. 新创建一个数据来存表

a199c904e3a41eef0db4d58f12d6ad33ca2.jpg

 

  1. 23张表如图

48e9d135fbae47640adcfc9b138fa981cba.jpg

 

 

    1. 了解数据库表前缀代表的函数

Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。

  1. ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
  2. ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
  3. ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,比如用户,组等等。
  4. ACT_HI_*: 'HI'表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
  5. ACT_GE_*: 通用数据, 用于不同场景下。

 

    1. 使用框架自动生成表(不建议)

步骤:

      1. 第一步:创建一个java项目
      2. 第二步:导入activiti中wars程序的所有jar包
      3. 第三步:再导入一个mysql的数据库驱动
      4. 第四步:提供一个配置文件,配置文件名必需为activiti-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

 

<!-- 流程引擎配置对象 -->

<bean id="processEngineConfiguration"

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

<property name="jdbcDriver"  value="com.mysql.jdbc.Driver"/>

<property name="jdbcUrl"  value="jdbc:mysql:///activiti_day1"/>

<property name="jdbcUsername"  value="root"/>

<property name="jdbcPassword"  value="123456"/>

<property name="databaseSchemaUpdate" value="true"/>

</bean>

 

<!-- 使用工厂创建流程引擎对象 -->

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

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

</bean>

</beans>

 

      1. 第四步:写一个单元测试
  1. 只要获取流程引擎对象,就会自动创建表
  2. 可以添加示例程序的log4j.properties来查看日志里更多信息输出
  3. 在activiti-engine-5.13.jar有数据库sql文件,用于自动创建数据库表

import org.activiti.engine.ProcessEngine;

import org.activiti.engine.ProcessEngines;

import org.junit.Test;

 

public class Test1 {

@Test

public void test1(){

ProcessEngine  pe = ProcessEngines.getDefaultProcessEngine();

}

}

 

    1. 设计一个请假流程图
  1. 在Eclipse中,利用activiti插件创建一个请假流程图
  2. 在每一个任务中,找到Main config的Assignee中,先固定每个任务的受理人

9c85ca97636d5e46f8b17a6a62710333057.jpg

 

    1. 部署流程定义
  1. 就是把流程存入数据库,写个单元测试代码
  2. 流程定义部署完后,会在act_re_deployment和act_re_procdef两张表存储数据,
  3. deployment的ID每次增加100
  4. 同一个流程的procdef表的version是递增的

@Test

public void test2(){

ProcessEngine  pe = ProcessEngines.getDefaultProcessEngine();

//创建部署构建器对象

DeploymentBuilder db = pe.getRepositoryService().createDeployment();

 

//读取流程定义文件(bpmn,png)

db.addClasspathResource("qjlc.bpmn");

db.addClasspathResource("qjlc.png");

 

//部署定义流程

Deployment deployment = db.deploy();

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

}

 

    1. 查询流程定义

public void test3(){

ProcessEngine  pe = ProcessEngines.getDefaultProcessEngine();

ProcessDefinitionQuery query = pe.getRepositoryService().createProcessDefinitionQuery();

 

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

for(ProcessDefinition pd : list){

System.out.print("ResourceName-" +pd.getResourceName() + ": ");

System.out.print("id-" + pd.getId() + ": ");

System.out.print("key-" + pd.getKey() + ": ");

System.out.print("name-" + pd.getName() + ": ");

System.out.println();

}

}

 

 

    1. 根据流程定义启动流程实例
  1. 就是把第一个请假申请任务跑
  2. 内部会操作act_re_execution和act_re_task两张表

public void test4(){

String pdId= "qjlc:1:304";

//启动流程实例

ProcessInstance pi = pe.getRuntimeService().startProcessInstanceById(pdId);

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

}

    1. 查询个人任务

public void test5(){

//查询个人任务

TaskQuery tq = pe.getTaskService().createTaskQuery();

tq.taskAssignee("zhangsan");

tq.orderByTaskCreateTime().desc();//时间排序

List<Task> tasks = tq.listPage(0, 10);//分页查询

for(Task task : tasks){

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

System.out.println("taskId:" + task.getId());

System.out.println("taskName:" + task.getName());

System.out.println("executionId:" + task.getExecutionId());

}

}

 

    1. 办理个人任务
  1. 请求申请需要被处理,处理中会操作act_re_task和act_hi_taskinst表
  2. 处理事,会进入下一个任务,往task表插入下一个流程的任务,比如请假申请后,下一个任务就是项目经理审批任务

@Test

public void test6(){

String taskId = "604";

//根据任务id办理个人任务

pe.getTaskService().complete(taskId);

}

 

    1. 部署流程定义的另一种方式zip文件

public void test7() throws FileNotFoundException{

//创建部署构建器对象

DeploymentBuilder db = pe.getRepositoryService().createDeployment();

 

File file = new File("C:\\process.zip");

FileInputStream fis = new FileInputStream(file);

 

ZipInputStream zis = new ZipInputStream(fis);

db.addZipInputStream(zis);

 

//部署定义流程

Deployment deployment = db.deploy();

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

}

 

    1. 删除流程定义

@Test

public void test8(){

//pe.getRepositoryService().deleteDeployment("901");

//加个true,删除process表相关记录,如果启动流程了实例,用下面的方法删除

pe.getRepositoryService().deleteDeployment("901", true);

}

 

    1. 查询部署对应的流程定义文件名称和输入流

@Test

public void test9(){

String deploymentId = "301";

List<String> names = pe.getRepositoryService().getDeploymentResourceNames(deploymentId);

for (String name : names) {

System.out.println(names);

//可以还原成文件,默认流程定义文件存在了act_ge_bytearr表

//InputStream in = pe.getRepositoryService().getResourceAsStream(deploymentId, name);

}

}

 

    1. 查询部署对应的流程定义图表

@Test

public void test10() throws IOException{

String processDefinitionId = "qjlc:1:304";//流程定义id

InputStream pngStream = pe.getRepositoryService().getProcessDiagram(processDefinitionId);

FileUtils.copyInputStreamToFile(pngStream, new File("c:\\t\\abc.png"));

}

 

    1. 删除流程实例

@Test

public void test11(){

String processInstanceId = "401";

String deleteReason = "不请假了";

pe.getRuntimeService().deleteProcessInstance(processInstanceId , deleteReason );

}

 

 

  1. Activity API总结
  1. 几个接口(和表有对应关系):

Deployment------act_re_deployment

ProcessDefinition-----act_re_procdef

ProcessInstance------act_ru_execution

Task-----act_ru_task

 

  1. 几个Query对象

DeploymentQuery------act_re_deployment

ProcessDefinitionQuery-----act_re_procdef

ProcessInstanceQuery------act_ru_execution

TaskQuery-----act_ru_task

 

  1. 几个Service

RepositoryService----操作部署表、流程定义表等静态资源信息表

RuntimeService----操作流程实例表、任务表等动态信息表

TaskService-----操作任务表

HistoryService----操作历史表

IdentityService----操作用户表、组表、关系表

 

 

 

 

 

  1. 流程变量
    1. 请假流程存在的问题
  1. 缺少请假原因和请假天数,后期可能还会有其它数据要补充
  2. activiti把这些数据称为流程变量,内部提供了一张act_ru_variable 表来存这些数据

7a04ba5930f39c4d20fe33f5bb7a07d1e3e.jpg

 

    1. 设置流程变量的方式
  1. 重新创建一个Java项目和数据库,这次用个报销流程讲解

41127b2b032e0c8401afaf4f4a5fc5020cb.jpg

 

      1. 第一种:【启动流程实例时设置流程变量

    //1.获取流程引擎

ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();

 

@Test

public void test1(){

 

//2.获取部署构建器对象

DeploymentBuilder db = pe.getRepositoryService().createDeployment();

 

//3.添加流程资源

db.addClasspathResource("com/gyf/activiti/variable/bxlc.bpmn");

db.addClasspathResource("com/gyf/activiti/variable/bxlc.png");

 

//4.部署

Deployment deployment = db.deploy();

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

}

/**

 * 启动流程实例时设置流程变量

 * */

@Test

public void test2(){

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

variables.put("bxyy", "成都出差机机票");

variables.put("bxje", "890");

pe.getRuntimeService().startProcessInstanceByKey("bxlc", variables);

}

 

      1. 第二种:【办理任务时设置流程变量

/**

 *办理任务时流程变量

 * */

@Test

public void test3(){

String taskId = "304";

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

variables.put("bxyy", "北京出差机机票");

variables.put("bxje", "891");

pe.getTaskService().complete(taskId,variables);

}

 

      1. 第三种:【使用RuntimeService的set方法流程变量

@Test

public void test4(){

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

//variables.put("bxyy", "上海出差机票");

variables.put("审批意见", "同意");

 

pe.getRuntimeService().setVariables("301", variables);

}

 

      1. 第四种:【用TaskService的set方法设置

@Test

public void test5(){

 

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

variables.put("审批意见", "不同意");

pe.getTaskService().setVariables("404", variables);

}

 

      1. 注意:
  1. 如果设置的是自定义的类型,需要实现序列号接口

9e5657347540af70f5f9f9fb48fade5479c.jpg

ecff1914eaf6a8b0c8ab83b6c76feeca7a9.jpg

 

    1. 读取流程变量的方式
      1. 方式一【使用RuntimeService的get方法获取

6b905cd58911983118177f21bd428425739.jpg

      1. 方式二【使用TaskService的get方法获取

a2d5eb989cc92e6de3759f228a0aff9e679.jpg

 

    1. 动态设置任务的候选人
      1. 第一步:在任务的Assignee写表达式

e2749c0f5ff03c20c6da8bb2316054ec641.jpg

 

      1. 第二步:在启动流程实现时,需要添加一个表达式里的变量值

8217806af2e0e4a802df0dfdb201b3dc718.jpg

 

  1. 组任务操作
    1. 候选人组任务(了解)
      1. 第一步:给任务添加多个用户

9638fea70fd5e2d925fbaf419b93467b7f6.jpg

 

      1. 第二步:重新部署流程和启动流程实现
      2. 第三步:办理第一个流程任务

dd82bae31d46179a34bfa2d40eb0d6200b9.jpg

 

      1. 第四步:根据用户id查询任务

0224180ac8fbd07921fe98be8d1a11dfe5f.jpg

 

      1. 第五步:拾取任务

3935598469e9fac73cb1cdd50534cf3d669.jpg

34ccb66a290aee971aaa7f88610a1560184.jpg

    1. 候选组组任务(重点)
      1. 第一步:设置一个财务分组id

371bed53eb37781512b4ffee318fdfccdab.jpg

 

      1. 第二步:重新部署流程并启动流程实例然后complete提交申请
      2. 第三步:添加组

c21022c24f2c264e674f723440f44b5047f.jpg

 

      1. 第四步:添加用户

07e7e8e8771500a6242eea5856b3ddf5c61.jpg

 

      1. 第五步:建立用户和组的关系

26bab3cf8b830e144aa492085f67cdb96f7.jpg

 

      1. 第六步:根据用户id或者组查询任务
  1. 注意:查询任务时,要先启动流程实现并输第一个任务

@Test

public void testProcessInstance(){

//启动流程实例:

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

variables.put("bxyy", "南京出差机机票");

variables.put("bxje", "890");

variables.put("employeeName", "小李");

pe.getRuntimeService().startProcessInstanceByKey("bxlc", variables);

}

 

@Test

public void testComplete(){

//处理第一个任务

pe.getTaskService().complete("2307");

}

@Test

public void test5(){

//查询组任务

TaskQuery tq = pe.getTaskService().createTaskQuery();

String userId = "1";

//tq.taskCandidateUser(userId);

tq.taskCandidateGroup("财务组");

List<Task> tasks = tq.list();

for(Task t:tasks){

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

}

}

 

 

      1. 第七步:拾起任务

pe.getTaskService().claim("2402", "1");

 

 

  1. 排它网关
    1. 排它网关流程图

4f8b0310aa541f43d5c1f9a05239de23884.jpg

 

    1. 测试网关
  1. 在开启流程实例时,必需设置流量变量qjts

public class GateWayTest {

//1.获取流程引擎

ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();

 

@Test

public void test1(){

 

//2.获取部署构建器对象

DeploymentBuilder db = pe.getRepositoryService().createDeployment();

 

//3.添加流程资源

db.addClasspathResource("com/huaizhi/activiti/gateway/qjlc.bpmn");

db.addClasspathResource("com/huaizhi/activiti/gateway/qjlc.png");

 

//4.部署

Deployment deployment = db.deploy();

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

}

 

@Test

public void test2(){

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

variables.put("qjyy", "感冒..");

variables.put("qjts",5);

pe.getRuntimeService().startProcessInstanceByKey("qjlc", variables);

 

}

@Test

public void test3(){

String taskId = "606";

pe.getTaskService().complete(taskId);

 

}

}

 

  1. activiti与spring整合
    1. applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx.xsd">

 

<!-- 配置数据源  -->

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url"  value="jdbc:mysql:///activiti_day2"/>

<property name="username"  value="root"/>

<property name="password"  value="123456"/>

</bean>

 

<!--  配置事务管理器 -->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

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

</bean>

 

<!-- 流程引擎配置对象 -->

<bean id="processEngineConfiguration"

 class="org.activiti.spring.SpringProcessEngineConfiguration">

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

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

</bean>

 

<!-- 使用工厂创建流程引擎对象 -->

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

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

</bean>

</beans>

 

    1. 单元测试

package com.huaizhi.activiti.springActivitiTest;

 

import java.util.List;

 

import org.activiti.engine.ProcessEngine;

import org.activiti.engine.repository.ProcessDefinition;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class SpringText {

 

@Test

public void test1() {

//1.创建spring工厂

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

 

//2.获取bean

ProcessEngine pe = (ProcessEngine) ac.getBean("processEngine");

 

List<ProcessDefinition> list = pe.getRepositoryService().createProcessDefinitionQuery().list();

 

//有流程定义打印,代表配置成功

for(ProcessDefinition pd : list){

System.out.println(pd.getKey());

}

}

}

 

 

 

  1. Bos项目集成activiti
    1. 第一步:在Bos数据库添加activiti所需要的表
    2. 第二步:将activiti与spring的整合转移到Bos项目中
  1. 导入jar包到项目【使用spring3.2以上版本,不需要添加spring-asm.jar 
  2. spring中配置processengin

<!-- 流程引擎配置对象 -->

<bean id="processEngineConfiguration"

 class="org.activiti.spring.SpringProcessEngineConfiguration">

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

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

</bean>

 

<!-- 使用工厂创建流程引擎对象 -->

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

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

</bean>

  1. 再配置activiti的各种service

<!-- 注册Service -->

<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>

<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>

<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>

<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>

  1. 测试下是否能获取到流程定义

4300ef0fced383d56c9d15265fa83084be1.jpg

 

  1. 流程定义管理模型
    1. 修改系统管理的菜单数据

706c042feca5c1046186a01f4d2697c575c.jpg9e6f480a97052601ac52568c6c487388cf8.jpg

 

  1. 在admin.json 添加两行数据

{ "id":"1004", "pId":"100", "name":"流程定义管理", "page":"processDefinitionAction_list.action"},

{ "id":"1005", "pId":"100", "name":"查看正在运行的流程实例", "page":"processInstanceAction_list.action"}

 

 

 

    1. 查看流程定义
  1. 创建ProcessDefinitionAction完成流程定义列表展现

3a3603fe1955577c6351d751c5bbbfcfedc.jpg

 

    1. 部署流程定义

32297e4a98eb71354584c442a05106ea4a5.jpg

 

    1. 查看流程定义图

第一步:修改jsp页面

<td>

   <a onclick="showPng('${id}')" class="easyui-linkbutton" data-options="iconCls:'icon-search'">查看流程图</a>

</td>

<script type="text/javascript">

function showPng(id) {

var url = "${pageContext.request.contextPath}/processDefinitionAction_viewpng?id=" + id;

//在新窗口中打开流程图

window.open(url);  

}

 

 

    1. 删除流程定义

2855d6710f81498badf1a293f6534141634.jpg

 

      1. 第一步:添加删除的js代码

function del(id){

var url = "${pageContext.request.contextPath}/processDefinitionAction_del?id=" + id;

$.messager.confirm("确认信息","你确定要删除流程定义",function(r){

if(r == false) return;

$.post(url,

function(data){

if(data == 1){//删除成功

$.messager.alert("提醒","删除成功","info",function(){

//刷新页面

window.location.href = "${pageContext.request.contextPath}/processDefinitionAction_list";

});

}else{

//删除失败

$.messager.alert("提醒","删除失败");

}

}

);

});

}

 

  1. 同步bos系统中用户和角色到activiti
  1. 删除数据库,把.sql的文件表创建下,导入auth_function表数据
  2. 内置一个admin帐号
  3. 配置文件中添加下面的代码,能自动创建activiti的表

2ea02fe27688c57c60112693c3a14222d5a.jpg

 

转载于:https://my.oschina.net/zhengchen/blog/3083575

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值