Activiti6简介

Activiti 是由 jBPM 的创建者 Tom Baeyens 离开 JBoss 之后建立的项目,构建在开发 jBPM 版本 1 到 4 时积累的多年经验的基础之上,旨在创建下一代的 BPM 解决方案,所以它是JBPM4的一个延申,因此第一个版本就是5.0
Activiti是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调度,所能能够很好的和spring整合

Activiti官网https://www.activiti.org/index.html

很多业务不用Activiti也能实现为什么要用Activiti?
使用activiti的好处:
1、减少对数据的访问,运行时中间表指挥存储它运行时的数据
2、提高系统的柔性,适应业务流程的变化
3、如果流程有变更,不适用工作流可能需要大量修改代码,降低系统开发和维护成本
4、开发系统时引入工作流的目的是为了分离业务逻辑和过程逻辑,让业务开发人员专注于核心的业务开发,过程逻辑的处理交给工作流引擎,且过程逻辑的变化对于核心业务逻辑不影响或者影响很少。

这是Activiti的核心内容,流程基本就靠着几大服务
7大接口

RepositoryService:提供一系列管理流程部署和流程定义的API。

RuntimeService:在流程运行时对流程实例进行管理与控制。

TaskService:对流程任务进行管理,例如任务提醒、任务完成和创建任务等。

IdentityService:提供对流程角色数据进行管理的API,这些角色数据包括用户组、用户及它们之间的关系。

ManagementService:提供对流程引擎进行管理和维护的服务。

HistoryService:对流程的历史数据进行操作,包括查询、删除这些历史数据。

FormService:表单服务。

入门案例

IDEA的插件下载比较方便,直接在Plugins里面搜索actiBPM下载就能用了,但是这个插件很早就停止更新了,有部分功能不是很便捷,所以推荐下载exlipce的插件
安装网上的博客很多,大家就直接去问度娘了
工作流Activiti6入门_数据库
首先导入pom依赖,还有我数据库需要用到的mysql

	<dependency>
          <groupId>org.activiti</groupId>
          <artifactId>activiti-engine</artifactId>
          <version>6.0.0</version>
      </dependency>
        <dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.44</version>
		</dependency>  

这是Activiti的配置文件,主要就是processEngineConfiguration,我们就是通过这个类来在数据库中创建表的
activiti.cfg.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration" id="processEngineConfiguration">
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti"></property>
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUsername" value="root"></property>
        <property name="jdbcPassword" value="123"></property>
		<!-- 数据库表更新策略 -->
        <property name="databaseSchemaUpdate" value="true"></property>

    </bean>
</beans>

这里我们画的是一个简单版的请假流程图,你先写申请,然后领导写是否同意,最后就结束了

然后我们用插件把流程图画好,流程图的后缀就是bpmn,这是一种文档的约束,我们画好后同样可以以xml的形式来查看
工作流Activiti6入门_xml_02
在exlipce中右击open就能查看,无需修改文件后缀
工作流Activiti6入门_流程图_03
我们打开这个流程图的文件形式是这样的,这就是以bpmn为约束的文件

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="myProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask1" name="写申请"></userTask>
    <userTask id="usertask2" name="写审核"></userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
    <sequenceFlow id="flow3" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="120.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="240.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="450.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="600.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="555.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="600.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="345.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="450.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="155.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="240.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

FirstAct.java
思路是这样的:我们获取流程引擎,然后我们就能通过我们的引擎获取之前说到的7个API接口,这里只用到了3个,然后读取我们的流程图文件,进入数据库开始执行流程,每个小任务的结束我都打印了一边,这样就可以清晰的看到过程,

package com.xy.demo;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

public class FirstAct {
	
	public static void main(String[] args) {
		//当这个类获取到时,数据库的表就已经生成好了
		ProcessEngine engine=ProcessEngines.getDefaultProcessEngine();
		//存储服务
		RepositoryService rs = engine.getRepositoryService();
		//运行时服务
		RuntimeService runtimeService = engine.getRuntimeService();
		//任务服务
		TaskService taskService = engine.getTaskService();
		//读取流程图文件
		rs.createDeployment().addClasspathResource("process/demo.bpmn").deploy();
		//这个myProcess就是bpmn文件打开最顶端的id
		ProcessInstance pi = runtimeService.startProcessInstanceByKey("myProcess");
		
		//普通员工完成请假的任务
		Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
		System.out.println("当前流程节点:"+task.getName());
		//每一个小任务的完成
		taskService.complete(task.getId());
		//老板完成审核任务
		task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
		System.out.println("但前流程节点:"+task.getName());
		taskService.complete(task.getId());
		//结束
		task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
		System.out.println("当前流程节点:"+task);
		
		engine.close();
		System.exit(0);
	}
}

最后流程结束,所以为null
工作流Activiti6入门_数据_04
然后看我们数据库,表也帮我们生成好了
工作流Activiti6入门_流程图_05

数据库表设计

它相对于Activiti5多了五张表
28张表
五大类型表
ACT_RE_ *:RE代表repository。具有此前缀的表包含静态信息,例如流程定义和流程资源(图像,规则等)。

ACT_RU_ *:RU代表runtime。这些是运行时表,其中包含流程实例,用户任务,变量,作业等的运行时数据。Activiti仅在流程实例执行期间存储运行时数据,并在流程实例结束时删除记录。这样可以使运行时表较小而又快速。

ACT_ID_ *:ID代表identity。这些表包含身份信息,例如用户,组等。

ACT_HI_ *:HI代表history。这些表包含历史数据,例如过去的流程实例,变量,任务等。

ACT_GE_ *:general数据,用于各种用例中。

你如果要熟练运行Activiti这个框架,那就一定要熟悉它的表是如何运作的
这里就来简单介绍一下
我们第一次运行,会有哪些数据产生

ACT_GE_
act_ge_property:存储Activiti的版本号的一些信息
act_ge_bytearray:存储你刚刚运行完的流程图和流程文件
工作流Activiti6入门_流程图_06
ACT_HI_ 历史记录表
act_hi_procinst:存储这任务的详细情况
工作流Activiti6入门_Activiti6入门_07
act_hi_identitylink:存储历史身份信息
act_hi_actinst:存储这所有的流程元素
工作流Activiti6入门_流程图_08
act_hi_taskinst:存储着历史的任务信息
工作流Activiti6入门_数据_09
ACT_RE_包含静态信息
act_re_deployment:你流程发布的时间和信息
工作流Activiti6入门_数据库_10
act_re_procdef:流程文件的具体信息
工作流Activiti6入门_数据库_11

ACT_RU_ 记录运行时的表
这个案例流程一结束,所有任务都关闭了,所以不会有数据,下次案例在介绍了

ACT_ID_ 包含用户、组等的信息
这个流程图比较简陋,所以这个数据也没有,也下次介绍了

end…