创建Activiti项目
虽然你现在啥都不知道,但是还是希望先把项目创建好,这一步基于springboot与mysql,会在mysql里创建许多activiti的表,这些表是activiti用来控制流程的手段,实际上,我们如果使用activiti自己去完成一项业务,也会慢慢的为流程创建各种各样的表,activiti相当于统一进行了汇总与格式化
如果想了解activiti项目的概念可以直接看下方activiti是什么?
1. 导入maven坐标
创建springboot项目,导入坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>
<!--mybatis-plus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
2. 配置文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///activiti?useUnicode=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8&characterEncoding=utf-8
username: root
password: 123456
# 坑点:此处如果不使用jdbc-url会报错
jdbc-url: jdbc:mysql:///activiti?useUnicode=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8&characterEncoding=utf-8
#意思是每次启动对自动创建的表进行检验
activiti:
history-level: full
check-process-definitions: false
3. 修改启动类上注释
@SpringBootApplication(exclude = {LiquibaseAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
SecurityAutoConfiguration.class})
@EnableTransactionManagement
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4. 添加对应配置文件注册bean
@Configuration
public class ActivitiConfig extends AbstractProcessEngineAutoConfiguration {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource activitiDataSource() {
return DataSourceBuilder.create().build();
}
public SpringProcessEngineConfiguration springProcessEngineConfiguration(PlatformTransactionManager transactionManager, SpringAsyncExecutor executor) throws IOException {
return baseSpringProcessEngineConfiguration(activitiDataSource(),transactionManager,executor);
}
}
5. 启动项目
会自动创建28个表:
- ACT_GE 通用类
- ACT_HI 历史记录类
- ACT_ID 用户信息类
- ACT_RE 流程实例类
- ACT_RU 运行时类
6. 安装actibpm插件
防止工具中文乱码
最后一行添加:-Dfile.encoding=UTF-8
7. eclipse插件
由于actibpm插件较久未更新,idea版本过高的话会导致各种奇怪的错误,方便起见可以使用eclipse的插件
具体安装教程可自行百度
关于画图
Activiti是什么?
本人处于初学阶段,所描述观点均使用中的个人理解,如有错误,欢迎指正,以下意在解决Activiti是什么?这一问题,不作太多扩展,大神可略过。
刚开始学习activiti,百度看了很多文章(结尾会给出各个文章索引),核心思想基本都是activiti是一个管理工作流的工具,或者说就是一个工作流引擎,通俗的说,就是Activiti引擎我们只要按照它已有的配置,来进行现有业务的对应,它就能够自动帮助我们完成以前不好控制的流程问题。
然而不知道你是否和我一样,看完这些一样一脸懵逼,目前我搭建了一套请假流程的demo,帮我学习理解了一些activiti的概念,我想从实际的项目出发来理解一下activiti。
我先总结一下activiti流程项目整体完成需要哪些部分:
流程定义->启动流程实例->各个用户节点按照流程顺序完成各自的任务->结束流程
以下代码不建议跟着使用,代码只是为了方便理解
1. 流程定义
先定个小目标,做一个请假流程的demo,画图:
这是十分简单的一个流程图,简单来说就是开始流程->学生申请请假->老师审批假条->结束流程。
那么画出这个图有什么用呢?这一张流程图其实就是对于你整个项目要实现功能的一个描述,也就是流程定义,可以这样认为,我们已经有了一个本项目的流程,而我们的程序可以根据这一流程定义,创建出多个流程实例。
在实际代码中流程定义可以使用activiti提供的api与我们画的图的代码文件完成:
@Autowired
private ProcessEngine processEngine;
//与流程定义和部署对象相关的Service
Deployment deployment = processEngine.getRepositoryService()//获取仓库
.createDeployment()//创建一个部署对象
.name("流程定义")//添加部署的名称
.addClasspathResource("LeaveDemo.bpmn")//从classpath的资源中加载,一次只能加载一个文件
.addClasspathResource("LeaveDemo.png")//从classpath的资源中加载,一次只能加载一个文件
.deploy();//完成部署
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称:" + deployment.getName());
当这一步完成的时候,我们相当于将这个流程告诉了程序,流程库里已经有这一个流程了,但是他并没有开始执行。
2. 启动流程实例
总结一句话:一个流程定义可以有多个流程实例,且由于activiti会把每一步记录进数据库,所以即使程序不运行了,只要数据库不改变,activiti内的流程实例,流程定义,执行步骤都不会消失
或者我更喜欢另一个理解,可以把activiti想象成整个java程序,流程定义是一个线程模板,流程实例是根据线程模板创建出来的线程,且就算程序运行,这些线程模板与线程也不会消失
/**
* 启动流程实例
*/
@Test
public void startProcessInstance(){
//1、流程定义的key,通过这个key来启动流程实例
String processDefinitionKey = "LeaveDemo";
//2、与正在执行的流程实例和执行对象相关的Service
// startProcessInstanceByKey方法还可以设置其他的参数,比如流程变量。
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey(processDefinitionKey,variables);//使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
System.out.println("流程实例ID:"+pi.getId());//流程实例ID
System.out.println("流程定义ID:"+pi.getProcessDefinitionId());//流程定义ID
// 流程实例ID:62501
// 流程定义ID:LeaveDemo:2:55004
}
这时我们的流程已经开始执行了,并且已经执行了第一步,那个圆圈,代表开始,并且进入申请请假等待学生提交申请,图中每一个方格都代表着一个任务,每个任务都有他的id,我们可以调用activiti的api直接指定该id任务完成。
3. 完成任务
/**
* 完成对应id的任务
*/
@Test
public void completePersonalTask() {
//任务ID,上一步查询得到的。
String taskId = "57509";
processEngine.getTaskService()//与正在执行的任务管理相关的Service
.complete(taskId);
System.out.println("完成任务:任务ID:" + taskId);
}
以上代码用于完成对应任务,拿我们的图距离,当学生完成提交申请的任务后,会进入老师审批任务的等待,当老师审批完成后,activiti发现后面只剩下结束了,说明任务都执行完毕了,结束该流程实例,或者可以理解成线程执行完毕。只是线程是活数据(储存于内存),activiti是死数据(储存于数据库)
4. 总结
这就是整体使用activiti的流程,需要注意的是,每个流程定义都只会存在一个,如果重复定义,会更新流程定义的版本。 activiti的流程定义多是用于对项目整体流程的一个设计与实施,但是具体的细节调用也是需要开发人员自己补充的。
5. 关于API
/**
* 运行时相关表
*/
@Autowired
private RuntimeService runtimeService;
/**
* 任务表, 可以查询 ACT_RU_ ACT_HI_
*/
@Autowired
private TaskService taskService;
/**
* 用户信息表
*/
@Autowired
private IdentityService identityService;
/**
* 通用类的表
*/
@Autowired
private RepositoryService repositoryService;
/**
* 门面接口,可以利用它创建出所有服务
*/
@Autowired
private ProcessEngine processEngine;
/**
* 历史记录表
*/
@Autowired
private HistoryService historyService;
如果想看api的具体使用,可参考: zhuanlan.zhihu.com/p/77289502
如果想具体了解各个服务api接口可看: juejin.cn/post/684490…