Activiti入門demo(Stringboot)

説明activiti版本5.22.0,boot版本2.*

一.準備

1.添加maven依賴

        <!--actity流程圖-->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>5.22.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.14</version>
            <scope>compile</scope>
        </dependency>

2.添加yml配置

spring:
  datasource:
    #url注意最後添加nullCatalogMeansCurrent=true
    url: jdbc:mysql://localhost/stu?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  activiti:
    database-schema-update: true #是否生成數據庫

3.添加配置類

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ActivitiDataSourceProperties {

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }
}
import com.alibaba.druid.pool.DruidDataSource;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.AbstractProcessEngineAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

@Configuration
public class ActivitiDataSourceConfig extends AbstractProcessEngineAutoConfiguration {
    @Resource
    private ActivitiDataSourceProperties activitiDataSourceProperties;

    @Bean
    public DataSource activitiDataSource() {
        DruidDataSource DruiddataSource = new DruidDataSource();
        DruiddataSource.setUrl(activitiDataSourceProperties.getUrl());
        DruiddataSource.setDriverClassName(activitiDataSourceProperties.getDriverClassName());
        DruiddataSource.setPassword(activitiDataSourceProperties.getPassword());
        DruiddataSource.setUsername(activitiDataSourceProperties.getUsername());
        return DruiddataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(activitiDataSource());
    }

    @Bean
    public SpringProcessEngineConfiguration springProcessEngineConfiguration() {
        SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();
        configuration.setDataSource(activitiDataSource());
        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        configuration.setJobExecutorActivate(true);
        configuration.setTransactionManager(transactionManager());
        configuration.setActivityFontName("宋體");
        configuration.setLabelFontName("宋體");
        configuration.setAnnotationFontName("宋體");
        //id生成器
        //configuration.setIdGenerator(new MyUUIDgenerator());
        return configuration;
    }


}

4.修改給起動類,添加exclude(排除一些自動加載)

@SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
        org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class
        ,org.activiti.spring.boot.SecurityAutoConfiguration.class
})
public class KissApplication {

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

}

5.這時啓動項目就會給你創建28張表

二.正文

1.創建一個流程模板(這裏是臨時創建一個,後面項目肯定是在線創建,你只用吧我生成的xml複製過去就行)

對應的xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1598860019016" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_2" name="StartEvent"/>
    <userTask activiti:candidateGroups="admin" activiti:exclusive="true" id="usetTaseOne" name="usetTaseOne"/>
    <userTask activiti:candidateGroups="admin2" activiti:exclusive="true" id="userTaskTwo" name="userTaskTwo"/>
    <endEvent id="_5" name="EndEvent"/>
    <sequenceFlow id="_6" sourceRef="_2" targetRef="usetTaseOne"/>
    <sequenceFlow id="_7" sourceRef="usetTaseOne" targetRef="userTaskTwo"/>
    <sequenceFlow id="_8" sourceRef="userTaskTwo" targetRef="_5"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="myProcess_1">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <omgdc:Bounds height="32.0" width="32.0" x="290.0" y="50.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usetTaseOne" id="Shape-usetTaseOne">
        <omgdc:Bounds height="55.0" width="85.0" x="265.0" y="145.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="userTaskTwo" id="Shape-userTaskTwo">
        <omgdc:Bounds height="55.0" width="85.0" x="260.0" y="260.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
        <omgdc:Bounds height="32.0" width="32.0" x="290.0" y="370.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="_2" targetElement="_3">
        <omgdi:waypoint x="306.0" y="82.0"/>
        <omgdi:waypoint x="306.0" y="145.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7" sourceElement="_3" targetElement="_4">
        <omgdi:waypoint x="305.0" y="200.0"/>
        <omgdi:waypoint x="305.0" y="260.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_4" targetElement="_5">
        <omgdi:waypoint x="306.0" y="315.0"/>
        <omgdi:waypoint x="306.0" y="370.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

2.流程模板創建完成,進入代碼部分

説明:下面的幾個service,都是activiti提供管理流程的

import com.hn.kiss.config.common.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Slf4j
@Api(tags = "ActivitiTestController", description = "流程引擎測試")
@RestController
@RequestMapping("/act")
@Validated
public class ActivitiTestController {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;

    //1.創建流程模板

    //2.發佈流程
    @ApiOperation("發佈流程")
    @PostMapping("/deploy")
    public CommonResult deploy(){
        //這裏用到的xml就是上文,我們創建生成的,項目根目錄的processes目錄
        repositoryService.createDeployment()
                .addClasspathResource("processes/test.bpmn20.xml")
                .deploy();
        log.info("Number of process definitions: " + repositoryService.createProcessDefinitionQuery().count());
        return CommonResult.success("發佈流程成功");
    }

    //3.啓動流程
    @ApiOperation("啓動流程")
    @PostMapping("/startProcess")
    public CommonResult startProcess(){
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1");

        // Verify that we started a new process instance
        log.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());
        return CommonResult.success("發佈流程成功");
    }

    //4.獲取指定用户組(或指定任務)的任務
    @ApiOperation("用户任務")
    @PostMapping("/userTasks")
    public CommonResult userTasks(){
        // 獲取去admin角色的任務
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("admin").list();
        for (Task task : tasks) {
            log.info("admin的任務: " + task.getName());
        }
        List<Task> tasks2 = taskService.createTaskQuery().taskCandidateGroup("admin2").list();
        for (Task task : tasks2) {
            log.info("admin2的任務: " + task.getName());
        }

        return CommonResult.success("任務獲取成功");
    }

    //5.完成指定任務
    @ApiOperation("完成任務")
    @PostMapping("/complete")
    public CommonResult complete(String id){
        taskService.complete(id);
        return CommonResult.success("任務完成成功");
    }


}

以此調用下面的流程就完成了一個基礎的流程