版本:
JDK:1.8
Spring Boot:2.6.7
Activiti:5.22.0
Idea:2020.3

Spring Boot集成activiti

Spring Boot集成activiti很简单,pom文件中添加如下依赖即可:

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter-basic</artifactId>
    <version>${activiti.version}</version>
</dependency>

下面是详细说明:

打开Idea,选择File -> New -> Project…

选择Spring Initializr,下一步

 

 

 

 

输入项目名activiti-demo,Java版本选择8以上,下一步:

 

 

 

选择项目所需依赖,这里我们选择MySQL数据库驱动和Spring Web(Activiti的依赖这里搜不到,一会儿我们手动加),继续下一步:

 

 

 

项目名称及存放路径,点完成:

 

 

 

创建项目后,打开pom.xml文件,添加上面说的Activiti依赖:

 

 

 

打开项目启动类ActivitiDemoApplication,修改@SpringBootApplication注释,添加exclude:

 
 

package com.example.activitidemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(
        exclude = {
                //activiti-spring-boot-starter-basic中的配置类,里面依赖了spring-security,不排除这个启动会报错
                org.activiti.spring.boot.SecurityAutoConfiguration.class})
public class ActivitiDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(ActivitiDemoApplication.class, args);
    }

}

修改配置文件application.properties,添加以下配置:

 
 

# 端口号,默认8080
server.port=8081
# 项目访问根路径
server.servlet.context-path=/activiti-demo

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/activiti-demo?characterEncoding=UTF-8&useUnicode=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456

# activiti验证自动部署(默认开启),activiti会自动部署processes目录下的任何BPMN 2.0流程定义
# 如果开启,需要在resources下创建processes文件夹,并在其中创建流程定义(例如:one-task-process.bpmn20.xml)
# 否则启动项目时会报错:class path resource [processes/] cannot be resolved to URL because it does not exist
spring.activiti.check-process-definitions=false

至此,代码部分均已完成,就是这么简单!

官方文档说明:只是在Spring Boot项目中添加依赖,就会在幕后发生很多事情:

  • 自动创建了内存数据库(如果没有配置spring.datasource.url的话),并传递给Activiti流程引擎配置
  • 创建并暴露了Activiti ProcessEngine bean(Activiti核心类)
  • 所有的Activiti服务都暴露为Spring bean(如RuntimeService、TaskService等)
  • 创建了Spring Job Executor

并且,processes目录下的任何BPMN 2.0流程定义都会被自动部署。

Activiti连接数据库

接下来,创建数据库,我们只用到了Activiti提供的25张表。从官网(或我的百度云
下载Activiti项目,下载后解压,目录是这样的:

 

 

 

 

新建activiti-demo数据库(mysql),然后执行activiti-5.22.0/database/create/下的三个sql文件(activiti.mysql.create.engine.sql、activiti.mysql.create.history.sql、activiti.mysql.create.identity.sql),如果你用的别的数据库找对应数据库的sql文件,执行后得到下面25张表:

 

 

 

现在,就可以启动代码试试了!

activiti-spring-boot-starter-basic中依赖了spring-boot-starter-jdbcspring-boot-starter-jdbc会自动配置数据源DataSource,Activiti默认使用该数据源(完全不需要手动指定数据源)。详情请参考springactiviti的官方文档说明。

spring-boot-starter-jdbc会检查是否配置了spring.datasource.url,如果没有配置将使用内存数据库,具体使用哪种数据库取决于classpath中的数据库驱动。数据库连接池默认使用HikariCP

 

 

 

 

Activiti修改配置

添加配置类ActivitiConfig,实现ProcessEngineConfigurationConfigurer接口,注意要加注释@Component,否则Activiti找不到。

ProcessEngineConfigurationConfigurer源码释义:接口的实现类可以对SpringProcessEngineConfiguration(Activiti的配置类)进行一些额外的配置,如果定义了这样的实现类,流程引擎配置创建且设置了默认值后将会调用它。

可以在这里设置数据源、事务管理器、全局事件监听器等配置信息。例如,我们可以添加如下配置避免流程图出现中文乱码:

 
package com.example.activitidemo.config;

import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
import org.springframework.stereotype.Component;

@Component
public class ActivitiConfig implements ProcessEngineConfigurationConfigurer {

    @Override
    public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
        processEngineConfiguration.setActivityFontName("宋体");
        processEngineConfiguration.setLabelFontName("宋体");
        processEngineConfiguration.setAnnotationFontName("宋体");
    }
}

引入官方流程设计器

其实Activiti已经为我们开发了一个web项目Activiti Explorer,里面包含了流程设计器、部署、任务管理等功能,我们要做的,就是把Activiti Explorer里流程设计器的相关代码引到自己的项目中来。

找到activiti-5.22.0/wars/activiti-explorer.war项目并解压,在resources下新建文件夹static/activiti,然后将activiti-explorer中的相关文件夹拷到static/activiti/下:

 

 

 

 

 

点击这里下载汉化包,放到static/activiti/下

然后需要修改app-cfg.js文件中的contextRoot:

 

 

 

找到activiti-5.22.0/libs/activiti-modeler-5.22.0-sources.jar并解压,将其中的三个类拷到项目中:

  • org.activiti.rest.editor.main.StencilsetRestResource.java 获取stencilset.json(流程设计器标签)
  • org.activiti.rest.editor.model.ModelEditorJsonRestResource.java 获取模型json数据
  • org.activiti.rest.editor.model.ModelSaveRestResource.java 保存模型
     

 

 

 

 

修改StencilsetRestResource:

 

 

 

修改ModelSaveRestResource:

用@RequestBody MultiValueMap<String, String> values来接会报错:Required request body is missing,我也不知道为啥,渴望哪位大佬路过来说下~~

 

 

 

pom.xml中添加activiti-modeler依赖:

activiti-modeler:Activiti建模组件:提供了保存模型、解析模型为json、获取stencilset.json(流程设计器标签)三个接口,已经把这三个类挪到demo项目中了(因为要改一些东西),但是没挪其它依赖,所以这里还是要把它放到pom中

  

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-modeler</artifactId>
    <version>${activiti.version}</version>
</dependency>

启动类上还要排除一下org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class这个类,不排除的话,打开设计器时会跳转到spring-security登录界面:

 

 

 

添加ModelController类,写一个创建模型并打开流程设计器的接口:

 
 

package com.example.activitidemo.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@RequestMapping("/model")
public class ModelController {

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 创建模型后,打开流程设计器
     * @param request
     * @param response
     */
    @GetMapping("/create")
    public void create(HttpServletRequest request, HttpServletResponse response) {
        try {
            //初始化一个空模型
            Model model = repositoryService.newModel();
            //设置一些默认信息
            String name = request.getParameter("name");
            String description = request.getParameter("description");
            String key = request.getParameter("key");
            if (name == null || name == ""){
                name = "";
            }
            if (description == null || description == ""){
                description = "";
            }
            if (key == null || key == ""){
                key = "";
            }

            ObjectNode modelNode = objectMapper.createObjectNode();
            modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
            modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
            modelNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);

            model.setName(name);
            model.setKey(key);
            model.setMetaInfo(modelNode.toString());

            // 保存模型
            repositoryService.saveModel(model);
            String id = model.getId();

            //完善ModelEditorSource
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");

            // 属性
            ObjectNode propertiesNode = objectMapper.createObjectNode();
            propertiesNode.put("process_id", model.getKey());
            propertiesNode.put("name", model.getName());
            editorNode.set("properties", propertiesNode);

             // 模板
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.put("stencilset", stencilSetNode);

            //添加模型编辑器资源 act_ge_bytearray表会新增一条数据
            repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));

            // 重定向到设计器界面
            response.sendRedirect(request.getContextPath() + "/activiti/modeler.html?modelId=" + id);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ok,大功告成,启动项目并在浏览器上访问http://localhost:8081/activiti-demo/model/create?name=cs出现下面界面就对啦(新建了一个名称为cs的模型):

 

 

 

 

最后,附上项目结构:

 

 

 

转自:https://www.jianshu.com/p/b4ab3bec009f