Activiti流程知识总结
Activiti的架构说明
ProcessEngineConfiguration
类,主要作用是加载activiti.cfg.xml配置文件ProcessEngine
类,主要作用是帮我们得到各种Service的接口,并且可以生成Activiti的工作环境,即25张表Service
接口,主要作用是快速实现对25张表的操作
RepositoryService
RuntimeService
TaskService
HistoryService
BPMN的ActivitiDesigner插件
IDEA中安装需要翻墙
或者从官网直接下载actiBPMN的插件,然后导入
https://plugins.jetbrains.com/plugin/7429-actibpm
画出流程定义图
注意乱码的产生,和png文件的生成
(IDEA比较麻烦,Eclipse可以一键生成)
部署流程方式
方式一:单个文件(bpmn文件,png文件)
方式二:先将bpmn文件和png文件压缩成zip,再通过zip流对象导入
主要工作
一 创建Activiti工程
- 新建Maven项目
- pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Activiti_new</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
</properties>
<dependencies>
<!-- activiti引擎-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<!-- activiti与spring整合的坐标-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<!-- BPMN模型-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti.cloud</groupId>
<artifactId>activiti-cloud-services-api</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>alfresco</id>
<name>Activiti Releases</name>
<url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
</project>
- resources下新建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"
xmlns:context="http://www.springframework.org/schema/context"
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/contex http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--数据源配置dbcp-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/activiti" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<!--activiti单独运行的ProcessEngine配置对象(processEngineConfiguration),使用单独启动方式
默认情况下:bean的id=processEngineConfiguration
-->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!--代表数据源-->
<property name="dataSource" ref="dataSource"></property>
<!-- <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="root" />-->
<!--代表是否生成表结构-->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
- resources下新建log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
- 在test中新建测试类,生成25张数据库表
public class demo {
@Test
public void test(){
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println(processEngine);
}
}
二 数据库表
数据库表的命名规则
act_re_*
: re表示repository,这个前缀的表包含了流程定义和流程静态资源(图片,规则等)act_ru_*
:ru表示runtime,这些运行时的表,包含流程实例,任务,变量,异步任务等运行中的数据,avtiviti只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录。这样在运行时表可以一直很小,速度很快act_hi_*
:hi表示history,这些表包含历史数据,比如历史流程实例,变量,任务等act_ge_*
:gen表示general。通用数据,用于不同场景下
三 Activiti服务架构图
通过processEngine可以返回各种服务,而这些服务提供了各种各样的方法操纵数据库中对应的一组表,帮我们简化操作。如repositoryService可以对如下表进行一定操作
3.1 activiti.cfg.xml
3.2 Service
3.2.1 Service创建方式
通过 ProcessEngine 创建 Service,Service 是工作流引擎提供用于进行工作流部署、执行、管理的服 务接口。 方式如下:
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
……
3.2.2 Service总览
3.3 ProcessEngine的两种创建方式
第一种
/*
* 测试类:作用是创建activiti所需的25张表*/
public class ActivitiTest {
@Test
public void GenTable(){
//1.创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration=
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//2.创建ProcessEngine对象
ProcessEngine processEngine = configuration.buildProcessEngine();
//可写可不写 3.输出processEngine对象
System.out.println(processEngine);
}
}
第二种
(条件:1.activiti的配置文件必须叫activiti.cfg.xml 2.bean的id必须叫"processEngineConfiguration")
ProcessEngine processEngine= ProcessEngines.getDefaultProcessEngine();
四 小试牛刀
4.1 流程部署
步骤1:resources下创建diagram文件夹,然后创建holiday.bpmn文件
步骤2:画流程定义图,给每个结点指定Assignee
步骤3:
- 将holiday.bpmn文件改后缀xml
- 然后右键xml文件,选择diagram出现流程图,点击上方的导出图片
- 将导出的图片命名为holiday.png,复制到diagram文件夹下
- 将xml文件改回bpmn后缀
步骤4:进行流程定义部署(即将流程图的内容存入数据库)
- 在main.java下创建com.hhu.activiti.ActivitiDeployment类,运行即可
//流程定义的部署
public class ActivitiDeployment {
public static void main(String[] args) {
//1.创建ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService实例
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.进行部署
Deployment deploy = repositoryService.createDeployment().addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("请假申请流程")
.deploy();
//4.输出一些部署信息
System.out.println(deploy.getName());
System.out.println(deploy.getId());
}
}
补充:压缩包部署方式
将holiday.png和holiday.bpmn压缩成holidayBPMN.zip文件,放在diagram下
public class ActivitiDeployment {
public static void main(String[] args) {
//1.创建ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService实例
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.转化出ZipInputStream流对象
InputStream is=ActivitiDeployment.class.getClassLoader().
getResourceAsStream("diagram/holidayBPMN.zip");
ZipInputStream zipInputStream=new ZipInputStream(is);
//4.进行部署
Deployment deploy = repositoryService.createDeployment().
addZipInputStream(zipInputStream)
.name("请假申请单流程")
.deploy();
/*//3.进行部署
Deployment deploy = repositoryService.createDeployment().addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("请假申请流程")
.deploy();*/
//4.输出一些部署信息
System.out.println(deploy.getName());
System.out.println(deploy.getId());
}
}
4.2 流程实例启动
- 流程定义:即我们画的BPMN图
- 流程部署:将流程定义的信息放入activiti的表中
- 流程定义和流程实例的关系:相当于类和对象,一个流程定义可以对应多个流程实例
启动流程实例的步骤:
- java.com.hhu.activiti下创建ActivitiStartInstance类
/*启动一个流程实例*/
public class ActivitiStartInstance {
public static void main(String[] args) {
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RunTimeService对象
RuntimeService runtimeService = processEngine.getRuntimeService();
//3,创建流程实例(需要知道流程定义的key)
ProcessInstance holiday = runtimeService.startProcessInstanceByKey("holiday");
//4.输出实例的相关信息
System.out.println("流程定义ID为"+holiday.getProcessDefinitionId());
System.out.println("流程部署ID为"+holiday.getDeploymentId());
System.out.println("流程实例ID为"+holiday.getId());
System.out.println("流程活动ID为"+holiday.getActivityId());
}
}
- 在
act_hi_actinst
表中查看活动实例的状态
其中开始
这个结点已经有了END_TIME_
表示已经结束
填写请假申请单
这个结点还没有END_TIME_
,表示未完成 - 在
act_hi_taskinst
表中查看当前正在进行的任务
显示张三
要去完成填写请假申请单
这个任务
4.3 任务查询
java.com.hhu.activiti下创建ActivitiTaskQuery类
/*
查询当前用户的任务列表*/
public class ActivitiTaskQuery {
public static void main(String[] args) {
//1.获取ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService对象
TaskService taskService = processEngine.getTaskService();
//3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("holiday")
.taskAssignee("张三")
.list();
//4.任务列表展示
for(Task task:taskList){
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("任务ID:"+task.getId());
System.out.println("任务负责人:"+task.getAssignee());
System.out.println("任务名称"+task.getName());
}
}
}
如果只有一个任务还可以调用singleResult
方法
Task task = taskService.createTaskQuery()
.processDefinitionKey("holiday")
.taskAssignee("王五")
.singleResult();
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("任务ID:"+task.getId());
System.out.println("任务负责人:"+task.getAssignee());
System.out.println("任务名称"+task.getName());
执行结果
流程实例ID:2501
任务ID:2505
任务负责人:张三
任务名称填写请假申请单
4.4 当前用户任务处理
- 创建ActivitiTaskComplete类
public class ActivitiTaskComplete {
public static void main(String[] args) {
ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = defaultProcessEngine.getTaskService();
//结合查询的任务ID号,完成该任务
taskService.complete("2505");
}
}
- 执行后查看
act_hi_taskinst
表
发现填写请假申请单
任务已经完成,下一个任务部门经理审批
出现 - 查看
act_hi_actinst
活动实例表
五 动态指定assignee
出现的问题及解决方法
1.导入Maven依赖过慢
C:\Users\余丰旭\.m2
下的settings.xml是默认设置
添加阿里云私服
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
2.设置 VM Options
打开idea,进入File–>Settings–>Maven–>Runner,将VM Options设置为 -DarchetypeCatalog=internal
设置下载源为国内
2.Mysql连接不上
解决方法:
在mysql安装文件中,找到 my.ini,在my.ini找到[mysqld],在后面加上skip-grant-tables,意思是开启不使用密码的权限,先重启mysql,然后用户mysql客户端软件登录上去,再添加root用户,并设置密码即可。记住,修改好后,要将刚才的修改再改回来,再重起一次mysql.
3.idea无法导入actiBPM插件
新版idea无法搜索到acitiBPMN插件,需要从网站上下载,然后外部导入
https://plugins.jetbrains.com/
搜索actiBPM下载
4. BPMN图中文乱码
见Activiti收藏夹
5. 右键diagram选项消失
在plugins中把uml的插件开启,重启idea