Appearance
首先不使用SpringBoot整合的方式使用Activiti7,循序渐进过度到在SpringBoot集成Activiti7,本文将介绍Activiti的作用,以及搭建学习的基本环境,只要数据库能自动创建即代表环境搭建成功。
为什么使用Activiti?
先来看如下一个流程,首先是员工填写出差申请,然后部门经理/财务审核以及人事审核全部通过后,流转到CTO审核或直接结束,此时我们可以使用Enum值的形式,记录当前状态,好像也能完成任务,但会出现几个问题:
- 如果需求变动,增加了两个流程,此时你需要修改大量代码,重新定义Enum值的含义,不亚于重写一个流程。
- 每次审核时都有记录,审核人是谁,审核时间是多少,会产生大量相似逻辑的代码。
- 如果系统中的流程有好几十种,且需求方频繁变更需求,那系统的复杂度兼职不可想象。
1.适用行业
消费品行业,制造业,电信服务业,银证险等金融服务业,物流服务业,物业服务业,物业管理,大中型进出口贸易公司,政府事业机构,研究院所及教育服务业等,特别是大的跨国企业和集团公司。
2.具体应用
- 关键业务流程:订单、报价处理、合同审核、客户电话处理、供应链管理等。
- 行政管理类:出差申请、加班申请、请假申请、用车申请、各种办公用品申请、购买申请、日报周报等凡是原来手工流转处理的行政表单。
- 人事管理类:员工培训安排、绩效考评、职位变动处理、员工档案信息管理等。
- 财务相关类:付款请求、应收款处理、日常报销处理、出差报销、预算和计划申请等。
- 客户服务类:客户信息管理、客户投诉、请求处理、售后服务管理等。
- 特殊服务类:ISO 系列对应流程、质量管理对应流程、产品数据信息管理、贸易公司报关处理、物流公司货物跟踪处理等各种通过表单逐步手工流转完成的任务均可应用工作流软件自动规范地实施。
环境搭建
新建一个空的Maven项目,在pom.xml添加依赖,需要指定Activiti镜像仓库,官方文档
xml
<repositories>
<repository>
<id>activiti-releases</id>
<url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases</url>
</repository>
</repositories>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<activiti.version>7.4.0</activiti.version>
<activiti.cloud.version>7.4.0</activiti.cloud.version>
<mysql.version>8.0.20</mysql.version>
<java.version>1.8</java.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<mybatis.version>3.4.5</mybatis.version>
<junit.version>4.12</junit.version>
<commonsio.version>2.6</commonsio.version>
<dbcp.version>1.4</dbcp.version>
</properties>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 模型处理 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 转换 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn json数据转换 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 布局 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- 链接池 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${dbcp.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commonsio.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</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>
</dependencies>
在resources
下新建log4j.properties
日志配置文件
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:\act\activiti.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
在resources
下新建activiti.cfg.xml
配置文件,注意数据库的账号密码,数据库新建一个空数据库即可
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.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/activity?nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- 引用数据源 上面已经设置好了-->
<property name="dataSource" ref="dataSource"/>
<!-- activiti 数据库表处理策略 -->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
新建测试类TestActiviti,在test/java/
下新建即可;jdk建议使用jdk11或更高版本,我最开始使用jdk8提示版本低了,如果公司项目使用jdk8自定百度搜索其他解决方案,jdk8高版本应该也可以。
java
public class TestActiviti {
@Test
public void testProcess() {
//创建ProcessEngineConfiguration
ProcessEngineConfiguration configuration =
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//通过ProcessEngineConfiguration创建ProcessEngine,此时会创建数据库
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println(processEngine);
}
}
查询数据库是否多出20多张表,如果没有表说明初始化失败,检查问题,尤其是数据库连接是否正确。
表分类 | 表名 | 备注说明 |
---|---|---|
一般数据 | ACT_GE_BYTEARRAY | 流程定义的bpmn和png文件 |
ACT_GE_PROPERTY | 系统相关属性 | |
流程历史记录 | ACT_HI_ACTINST | 历史的流程实例 |
ACT_HI_ATTACHMENT | 历史的流程附件 | |
ACT_HI_COMMENT | 历史的说明性信息 | |
ACT_HI_DETAIL | 历史的流程运行中的细节信息 | |
ACT_HI_IDENTITYLINK | 历史的流程运行过程中用户关系 | |
ACT_HI_PROCINST | 历史的流程实例 | |
ACT_HI_TASKINST | 历史的任务实例 | |
ACT_HI_VARINST | 历史的流程实例变量表 | |
用户组表 | ACT_ID_GROUP | 身份信息-组信息 |
ACT_ID_INFO | 身份信息-信息 | |
ACT_ID_MEMBERSHIP | 身份信息-用户和组关系的中间表 | |
ACT_ID_USER | 身份信息-用户信息 | |
流程定义表 | ACT_RE_DEPLOYMENT | 流程定义部署表 |
ACT_RE_MODEL | 模型信息 | |
ACT_RE_PROCDEF | 流程定义信息 | |
运行实例表 | ACT_RU_EVENT_SUBSCR | 运行时事件 |
ACT_RU_EXECUTION | 运行时流程执行实例 | |
ACT_RU_IDENTITYLINK | 运行时参与者的用户信息 | |
ACT_RU_JOB | 运行时作业 | |
ACT_RU_TASK | 运行时任务 | |
ACT_RU_VARIABLE | 流程运行时变量表,记录当前流程可使用的变量,包括 global 和 local |
扩展-bean名称更改
创建Activiti还有其他写法,注意看activiti.cfg.xml
中bean的id,这个id是可以更改的,只需要在初始化的时候指定即可。
java代码中指定
java
@Test
public void testProcess() {
//创建ProcessEngineConfiguration,指定beanName
ProcessEngineConfiguration configuration =
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml","processEngineConfiguration");
//通过ProcessEngineConfiguration创建ProcessEngine,此时会创建数据库
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println(processEngine);
}
扩展-数据库连接信息写到bean中
数据库连接信息可以直接写到bean内部,不提取出来
xml
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- 可以不使用引用数据源的方式,直接写在bean内部 -->
<!-- <property name="dataSource" ref="dataSource"/>-->
<property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/activity?nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8"/>
<property name="jdbcUsername" value="root"/>
<property name="jdbcPassword" value="root"/>
<property name="jdbcMaxActiveConnections" value="3"/>
<property name="jdbcMaxIdleConnections" value="1"/>
<!-- activiti 数据库表处理策略 -->
<property name="databaseSchemaUpdate" value="true"/>
</bean>