Activiti 流程引擎(一)

1.Activiti 流程设计器集成与使用

(1)使用 Eclipse 集成 Activiti 流程设计器

下载插件

百度云链接: https://pan.baidu.com/s/1uVbckVTD_puqf0G7x5PXpg 密码:2rbm

解压并放到 Eclipse 目录下

  1. Eclipse 插件安装方法

Eclipse 插件安装 4 种方法
https://cloud.tencent.com/developer/article/1332826

Eclipse 使用 dropins 的插件安装方式
https://blog.csdn.net/mafly008/article/details/11093549

  1. 安装 activiti-designer-5.14.1 插件
  • 将 activiti-designer-5.14.1 内的两个文件:features 和 plugins 放到 eclipse 的 dropins/activiti-designer-5.14.1 文件内
    在这里插入图片描述
  • eclipse安装activiti需装eclipse插件20170325内的四个文件放到 eclipse 根目录的 plugins 内
    在这里插入图片描述

创建 Activiti 项目

  • File -> New -> Project -> Activiti -> Activiti Project -> Next -> 输入 Project name -> Finish

设计流程

  • Project name/src/main/resources/diagrams 包用于存放设计的流程定义 XML 文件
  • diagrams下 -> New -> Other -> Activiti Diagram -> Next -> 文件名 -> Finish

以不同格式查看流程内容

  • 右击流程文件 -> Open With

打开流程属性页面

  • Window -> Show view -> Properties

(2)使用 IDEA 集成 Activiti 流程设计器

  • actiBPM 是 IDEA 中的 Activiti 插件,用于提供可视化流程设计能力。

2.流程组件介绍

https://wenku.baidu.com/view/e0f7ce06de36a32d7375a417866fb84ae45cc33e.html

(1)事件

空启动事件

必须⼈⼯去启动⼀个流程。每启动⼀次,产⽣⼀个新的流程实例。只能通过API调⽤startProcessInstanceByXXX⽅法启动⼀个流程实例。⼤多数流程都是以此⽅式开始的,⽅便⽤户⼿动发起流程实例。

定时器启动事件

定时器启动事件⽤于在给定的时间点创建流程实例。可⽤在只启动⼀次的流程中,也可在特定时间间隔下启动。模型⼀旦部署,将会⾃动调度计时器时间,不需要通过API调⽤startProcessInstanceByXXX来启动流程实例,但还是可以通过API调⽤startProcessInstanceByXXX来再次启动。

结束事件

(2)活动列表

用户活动

⽤于对需要由⼈⼯参与者完成的⼯作建模。当流程执⾏到达这样⼀个⽤户任务时,将在分配给该任务的⽤户或组的任务列表中创建⼀个新任务。

代理人 assignee

处理人唯一

<userTask id="usertask1" name="商务采购" activiti:assignee="${assignee}" ></userTask>
候选人 candidateUsers

处理人多个,字符串以" , "分隔

<userTask id="usertask2" name="商务采购" activiti:candidateUsers="${candidateUsers}"> </userTask>
候选组 candidateGroups

在act_id_group中存储的组id

<userTask id="usertask3" name="商务采购" activiti:candidateGroups="${candidateGroups}"> </userTask>

服务任务

⽤于调⽤外部Java类。当下⼀个节点需要⾃动执⾏⼀些操作,并且这个节点不需要任何的⼈⼯⼲涉。操作主要步骤分为:设计流程、编写委托类、把委托类设置到流程的监听类上⾯。

脚本任务

⼀般是⽤在当前的监听器或者监听服务类都不能满⾜的情形下。

邮件任务

Activiti允许通过向⼀个或多个收件⼈发送电⼦邮件的⾃动邮件。

(3)网关

排它网关

只会选择⼀条顺序流。当多条顺序流的条件都计算为true时,其中在XML中定义的第⼀条(也只有这条)会被选择,⽤于继续流程。如果没有可选的顺序流,会抛出异常。
在网关的连线上配置判断条件。
在这里插入图片描述

https://blog.csdn.net/wang0907/article/details/120800372

并行网关

⽤于对流程中的并发性进⾏建模。它允许分叉到多个执⾏路径或连接多个传⼊的执⾏路径。

(4)结构列表

子流程

⼦流程完全是在⽗流程中定义 的(这就是为什么它通常被称为嵌⼊式⼦流程)。⼦进程只能有⼀个⽆启动事件,不允许有其他启动事件类型。⼦流程必须⾄少有⼀个end事件。BPMN 2.0规范允许省略⼦流程中的 开始和结束事件,但是当前的Activiti-5.22.0实现不⽀持这⼀点

3.Activiti 数据库设计和模型映射

Activiti 支持多种主流关系型数据库,如 DB2、MySQL、Oracle 等。Activiti 遵循以下命名规则:表名由以下划线连接的部分组成,其中第一部分固定以 ACT 开头,第二部分是表示表用途的两个字母标识,用途与服务的 API 对应,第三部分表示存储的内容。例如,ACT_HI_PROCINST 表示 Activiti 的历史流程实例表。

根据 Activiti 表的命名规则,可以将 Activiti 的数据表划分为以下 5 大类。

  • 通用数据表:用于存放流程或业务使用的通用资源数据,这类表以 ACT_GE_ 为前缀,其中 GE 表示 general。
  • 流程存储表:用于存放流程定义文件和部署信息等,这类表以 ACT_RE_ 为前缀,其中 RE 表示 repository。
  • 身份数据表:用于存放用户、组及关联关系等身份信息,这类表以 ACT_ID_ 为前缀,其中 ID 表示 identity。
  • 运行时数据表:用于存放流程执行实例、任务、变量等流程运行过程中产生的数据,这类表以 ACT_RU_ 为前缀,其中 RU 表示 runtime。
  • 历史数据表:用于存放历史流程实例、变量和任务等历史记录,这类表以 ACT_HI_ 为前缀,其中 HI表示 history。
    请添加图片描述

3.1 通用数据表

  • 通用数据表指 Activiti 中以 ACT_GE_ 开头的表,用于存放流程或业务使用的通用资源数据,主要包括 ACT_GE_BYTEARRAY 资源表和 ACT_GE_PROPERTY 属性表。
    • ACT_GE_BYTEARRAY 资源表用于存储与工作流引擎相关的资源数据,Activiti 使用该资源表保存流程定义文件内容、流程图片内容和序列化流程变量等二进制数据。
    • ACT_GE_PROPERTY 属性表用于存储整个工作流引擎级别的属性数据,Activiti 将全部属性抽象为 key-value,每个属性都有相应的名称和值。

3.2 流程存储表

  • 流程存储表指 Activiti 中以 ACT_RE_ 开头的表,用于存储流程定义和部署信息等,主要包括 ACT_RE_MODEL 表、ACT_RE_DEPLOYMENT 表和 ACT_RE_PROCDEF 表。
    • ACT_RE_MODEL 表即流程设计模型表,该数据表主要用于存储流程的设计模型。
    • ACT_RE_DEPLOYMENT 表即部署信息表,该表主要用于存储流程定义的部署信息。Activiti 一次部署可以添加多个资源,资源保存在 ACT_GE_BYTEARRAY 资源表中,部署信息则保存在该表中
      • ID_ 部署记录ID
      • CATEGORY_ 分类:在部署时定时,可用来对流程分类
    • ACT_RE_PROCDEF 表即流程定义数据表,该表主要用于存储流程定义信息。Activiti 部署流程时,除了将流程定义文件存储到资源表之外,还会解析流程定义文件内容,生成流程定义保存在该表中。
      • ID_ 流程定义ID

3.3 身份数据表

  • 身份数据表指 Activiti 中以 ACT_ID_ 开头的表,用于存储用户、组、关系等身份信息,主要包括 ACT_ID_USER 表、ACT_ID_INFO 表、ACT_ID_GROUP 表和 ACT_ID_MEMBERSHIP 表。
    • ACT_ID_USER 表即用户表,该表主要用于存储用户基本信息数据,不是必须的。
      • ID_ 用户ID
    • ACT_ID_INFO 表即用户账号信息表,该表主要用于存储用户账号、用户信息等。Activiti 将信息分为用户、用户账号和用户信息 3 种信息类型。其中,用户保存在 ACT_ID_USER 表中,用户账号和用户信息保存在该表中
      • ID_ 账号ID
      • USER_ID 用户ID
      • PASSWORD 密码
    • ACT_ID_GROUP表即用户组表,该表主要用于存储用户组数据。
      • ID_ 用户组ID
      • NAME_ 用户组类型
    • ACT_ID_MEMBERSHIP 表即用户与用户组关系表,该表主要用于存储用户与用户组的关系,一个用户组可以有多个用户,一个用户也可以隶属于多个用户组

4.流程操作

RepositoryService

RepositoryService是Activiti的仓库服务类。所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片

(1)流程部署

主要对应操作表:

  • act_re_deployment(部署对象表):存放流程定义的名称和部署时间,每部署一次增加一条记录。
  • act_re_procdef(流程定义表):存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。当流程定义的key相同的情况下,使用的是版本升级
  • act_ge_bytearray(资源文件表):存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的,都是以二进制形式存储在数据库中。
@Configuration 
public class BPMNResourceConfig { 

@Autowired private 
RepositoryService repositoryService;

	@Bean("testDeployment") 
	public Deployment testDeployment() { 
		// DeploymentBuider属于部署层
		DeploymentBuider deploymentBuilder = repositoryService.createDeployment()
		Deployment deployment = deploymentBuilder.key("test").name("测试流程").addClasspathResource("process/testProcess.bpmn").deploy()
		log.info(deployment.getKey());   // 部署英文名:test
		log.info(deployment.getId());    // 系统生成的部署Id
		log.info(deployment.getKey());   // test
		return deployment; 
	} 
}

(2)流程定义

在启动实例时会用到流程的KEY。

@Configuration 
public class BPMNTemplateConfig { 

	@Autowired 
	private RepositoryService repositoryService;
	
	@Resource(name = "testDeployment")
	private Deployment testDeployment;
	
	@Bean("testProcessDefinition")
	public ProcessDefinition testProcessDefinition() {
		ProcessDefinitionQuery query =  repositoryService.createProcessDefinitionQuery();
		ProcessDefinition processDefinition = query.deploymentId(testDeployment.get Id()).singleResult()
		log.info(processDefinition.getKey());   // bpmn中Process的Id, 流程英文名, 如 operationIndex
		log.info(processDefinition.getId());    // operationIndex:2:38833-11vsf-1121f-12efac-12e1113
		log.info(processDefinition.getName());  // bpmn中Process的Name, 流程中文名
		log.info(processDefinition.getDeploymentId());   // 流程部署Id
		log.info(processDefinition.getResourceName());   // 资源名称, 如 process/operationIndex.bpmn
		return processDefinition;
	} 
}

(3)查询流程部署

public void testDeploymentQuery(){
    List<Deployment> myEvection = repositoryService.createDeploymentQuery()
            .processDefinitionKey(testProcessDefinition.getKey())  // 流程定义的Key
            .orderByDeploymenTime().desc()
            .list();
    for (Deployment deployment : myEvection) {
        System.out.println(deployment);
    }
}

(4)删除流程部署

public void testDeploymentQuery(){
    List<Deployment> myEvection = repositoryService.createDeploymentQuery()
            .processDefinitionKey(testProcessDefinition.getKey())  // 流程定义的Key
            .orderByDeploymenTime().desc()
            .list().get(0);
    if(myEvection != null){
    	// 普通删除, 如果当前规则下有正在执行的流程, 则抛出异常
        // repositoryService.deleteDeployment(deployment.getId());
        // 级联删除, 会删除和当前规则相关的所有信息, 正在执行的信息, 也包括历史信息
        repositoryService.deleteDeployment(myEvection.getId(), true);
    }
}

(5)流程定义挂起

某些情况可能由于流程变更需要将当前运行的流程暂停而不是直接删除,流程暂停后将不会继续执行。

repositoryService.suspendProcessDefinitionById(processDefinitionId,true,null);

(6)流程定义激活

repositoryService.activateProcessDefinitionById(processDefinitionId,true,null);

(7)获取bpmn详情(☆☆☆)

// 所有bpmn节点的信息
BpmnModel bpmnModel = repositoryService.getBpmnModel(historyTaskInfo.getProcessDefinitionId());
Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements();
Iterator<FlowElement> iterator = flowElements.iterator();
while (iterator.hasNext()) {
	FlowElement next = iterator.next(); 
	System.out.println(next.getId() + "-" + next.getName());  // startevent1-流程开启
}

// 指定bpmn中节点的信息
UserTask> userTask = (UserTask)bpmnModel.getMainProcess().getFlowElements(historyTaskInfo.getProcessDefinitionId());
log.info(userTask.getCandidateUsers(), userTask.getCandidateGroups());

RuntimeService

是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息。

(1)开启流程

主要对应操作表:

  • act_ru_execution:如果是用户任务节点,同时也会在act_ru_task添加一条记录。
  • act_ru_identitylink:任务参与者数据表。主要存储当前节点参与者的信息。
public String startInstance(){ 
	Map<String,Object> varMap = new HashMap<>(); 
	varMap.put("apply","A6582"); // user
	varMap.put("checkGroup", "2001");  // group
	ProcessInstance processInstance = runtimeService.startProcessInstanceById(testProcessDefinition.getId(), varMap); 
	return processInstance.getId(); 
}

(2)挂起流程实例

runtimeService.suspendProcessInstanceById(processInstanceId);

(3)激活流程实例

runtimeService.activateProcessInstanceById(processInstanceId);

(4)删除流程

runtimeService.deleteProcessInstance(processInstanceId, "删除测试");

(5)流程参数设置

https://blog.csdn.net/ITWANGBOIT/article/details/106507332

runtimeService.getVariable(processInstance.getId(), "apply");  // A6582
runtimeService.setVariable(processInstance.getId(), "apply", "A6582");
runtimeService.setVariableLocal(processInstance.getId(), "apply", "A6582"); // 只有当前子流程能拿到

TaskService

是activiti的任务服务类。可以从这个类中获取任务的信息。

(1)查询task(未处理任务☆☆☆)

Task task = taskService.createTaskQuery()
			.processInstanceId(processInstance.getId())
			.taskCandidaterOrAssigned("A6582")
			.singleResult();

(2)任务参数设置

https://blog.csdn.net/ITWANGBOIT/article/details/106544672

taskService.getVariable(task.getId(), "apply");
taskService.setVariable(task.getId(), "apply", "A6582");
taskService.setVariableLocal(task.getId(), "apply", "A6582"); // 只有当前任务能拿到

(3)完成任务

act_ru_task:对于执行完的任务,activiti将从act_ru_task表中删除该任务,下一个任务会被插入进来。

public void complete( @RequestParam(name = "userId") String userId, @RequestParam(name = "instanceId") String instanceId){ 
	Task task = taskService.createTaskQuery().processInstanceId(instanceId).taskCandidateOrAssig ned(userId).singleResult(); 
	taskService.complete(task.getId()); 
	taskService.addComment(task.getId(), instanceId, comment); 
	List<Comment> com = taskService.getTaskComment(task.getId()); 
}

HistoryService

https://www.jianshu.com/p/9b1ea194da13

是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。

createHistoricProcessInstanceQuery 当前、已结束的流程实例信息

historyService.createHistoricProcessInstanceQuery()
  .finished()
  .processDefinitionId("XXX")
  .list();

createHistoricActivityInstanceQuery 流程节点执行信息

historyService.createHistoricActivityInstanceQuery()
  .finished()
  .processInstanceId("XXX")
  .list();

createHistoricVariableInstanceQuery 流程或任务变量

historyService.createHistoricVariableInstanceQuery()
  .processInstanceId("XXX")
  .list();

createHistoricTaskInstanceQuery 当前、已完成、已删除任务实例信息(历史节点☆☆☆)

list<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
  .processInstanceId("XXX").list();
list.forEach(historyTaskInfo -> {
	log.info(historyTaskInfo.getName());  // 节点名称
	log.info(historyTaskInfo.getId());  // 任务Id
	log.info(historyTaskInfo.getStartTime());  // 开始时间
	log.info(historyTaskInfo.getEndTime());  // 结束时间
	log.info(historyTaskInfo.getDeleteReason());   // 删除原因
	log.info("处理人");
	log.info("部门");
})

5.监听器

https://blog.csdn.net/sadoshi/article/details/104698749/

任务监听器

顾名思义是监听任务的。任务监听器的生命周期如下图所示,会经历assignment、create、
complete、delete。当流程引擎触发这四种事件类型时,对应的任务监听器会捕获其事件类型,再按照
监听器的处理逻辑进行处理。

public class MyTaskListener implements TaskListener{
 
	public void notify(DelegateTask delegateTask) {
		String eventName = delegateTask.getEventName();
		if ("create".endswith(eventName)) {
		}
		if ("complete".endswith(eventName)) {
		}
	}

在这里插入图片描述

执行监听器

监听流程的所有节点和连线。主要有start、end、take事件。其中节点有start、end两种
事件,而连线则有take事件。

public class MyExecutionListener implements ExecutionListener {
 
	public void notify(DelegateExecution execution) throws Exception {
		String eventName = execution.getEventName();
		if ("start".endswith(eventName)) {
		}
		if ("end".endswith(eventName)) {
		}
	}

下图是执行监听器的生命周期:
在这里插入图片描述
在插件中Listeners指定监听器的代码位置(org.activiti.engine.delegate.DelegateExecution)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工作流 Activiti 的学习总结(六) Activiti 的安装详细过程 activiti-5.6 的安装 项目中采用最新的 Activiti 版本为 5.6GA 的 activiti REST 方式访问相关的 REST WebService 服务, activiti 提供了 对 mysql 、 oracle 、 postgres 的全面支持。 demo 的安装脚本比之前的版本都有 了很大的优化,基本上按教程就能顺利 demo , 真正达到了 GA 的效果了。为此我将在使用 mysql 的安装过程及遇到的一些小问 题总结记录了下来。但是我们项目采用 H2 数据库 ( Generic H2 Server )方式存储数据(安装成功之后在 ${activiti_home}\apps\h2 目下保存数据文件 {activiti_db}.h2.db ) 和 {activiti_db}.lobs.db. 如下是在 windows XP 环境下使用 mysql 数据库的安装实录: 一)下载 activiti-5.6.zip 二)将 activiti-5.6zip 解压到指定目录,假设为“C: \mash_activiti- 5.6”, 注意下面提到的路径均是相对于该路径而言 三)检查数据库类型 打开文件“setup \ build.properties”修改 db=h2 (采用默认为 h2 )。 四)配置 H2 数据库 创建名称为 activiti 的空数据库,连接帐号设为 sa ,密码也设为 activiti 。 ( 如果不喜欢默认的连接配置,可以修改文件“setup \ build.h2.properties”中 相应的属性值) 五)预下载一些必需的文件到“C: \ downloads”(备注这一步可以不执行,非必 须的,在网络比较好的情况下,使用 ant 自动下载 ) “C: \ downloads”这个路径是在 build.properties 中通过属性 “downloads.dir”定义的,也可以手动修改指定其他位置。 如果确保网络环境很顺畅, 这一步也可以不做, 安装脚本会自动下载, 由于之前 的版本我安装时经常下载中断, 导致文件损坏、 安装异常, 所以我习惯了先预先 下载,保证安装顺畅点。主要下载如下 2 个文件,左侧为下载地址,右侧为下载 后保存的文件名: 1 ) http://mirrors.enquira.co.uk/apache/apache-tomcat-6.0.32.zip (http://activiti.org/downloads/apache-tomcat-6.0.32.zip) --> apache-tomcat-6.0.32.zip ( 2.71MB ) 2 ) http://activiti.org/downloads/activiti-modeler-5.6.war --> activiti-modeler-5.6.war ( 31.8MB ) 六)修改浏览器的可执行文件路径(非必须) 打开文件“setup \ build.xml”修改属性 windows.browser 的值为浏览器的启动 文件对应的位置。如我一直使用 chrome ,配置如下: <property name="windows.browser" value="C:/Documents and Settings/dragon/Local Settings/Application Data/Google/Chrome/Application/chrome.exe" /> 修改这个的目的是方便下面的 "ant demo.start" 结束后自动打开浏览器访问相 关演示模块的首页。 七)检查一下你的电脑是否已经使用了 tomcat 服务 如果使用了 tomcat 服务, 得停掉, 否测会冲突。 顺便检查一下 8080 端口有没有 被占用,否测也会冲突导致安装失败。 八)安装 apache-ant-1.8.2 和 jdk1.5+ 环境 主要是设置环境变量 ANT_HOME 和 JAVA_HOME ,并 将 %ANT_HOME%\bin 、 %JAVA_HOME%\bin 设置到 path 环境变量中。 九)一切就绪后就可以开始体验了 命令行切换到“setup/",运行 "ant demo.start" ,等待整个安装过程自动完成 吧,安装完毕后默认会自动打开浏览器 十)测试是否安装成功 http://localhost:8080/activiti-probe 采用默认 admin 用户登录: 登录名称: kermit 登录密码: kermit 十一) activiti 手工启动方式如下: activiti 默认下载的 tomcat 和 h2 的安装目录为 ${activiti_home}/apps 目录如 (C:\mash_activiti-5.6\apps) 下面。 启动的 activit 服务需要 1. 先启动 H2 数据库控制台 ( C:\mash_activiti-5.6\apps\h2\h2_console.start.bat ,控制台 web 访问开 放端口为 8082 ) 2. 再启动 H2 数据库访问服务 ( C:\mash_activiti-5.6\apps\h2\h2.start.bat , H2 程序访问开放端口为 9092 ) 我在安装使用过程中遇到如下一些问题: tomcat 控制台显示的中文乱码 解决办法:修改文件 apps\apache-tomcat-6.0.32\conf\logging.properties , 增加如下一行的配置: java.util.logging.ConsoleHandler.encoding = GBK

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值