Activiti6 入门学习

538 阅读6分钟

创建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…

本文参考文章:

juejin.cn/post/684490…

juejin.cn/post/684490…

juejin.cn/post/684490…

www.cnblogs.com/SIHAIloveYA…