SpringBoot集成Activiti7.0

wuchangjian2021-11-03 14:14:44编程学习

需求:项目需要引入相关的工作流框架,为了熟悉相关的工作流框架,选择了Activiti7.0和SpringBoot集成进行相关学习

1、引入相关maven依赖包

    <properties>
        <activiti.version>7.1.0.M5</activiti.version>
    </properties>
    
    
       <!-- 引入activiti7依赖 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-image-generator</artifactId>
            <version>${activiti.version}</version>
        </dependency>

2、Activiti的相关yaml配置

spring:
  #Activiti7配置
  activiti:
    # 自动部署验证设置:true-开启(默认)、false-关闭
    check-process-definitions: false
    #自动创建表
    #database-schema-update: drop-create
    database-schema-update: false
    #使用历史表
    history-level: full
    db-history-used: true
    # 关闭自动部署
    deployment-mode: never-fail
    #自动部署文件路径前后缀
    #process-definition-location-prefix: classpath:/bpm/
    #process-definition-location-suffixes: **.bpmn,**.bpmn20.xml

3、引入测试案例的bpmn文件(askForLeaveBpm.bpmn)

<?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="m1620381003109" 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="开始"/>
    <userTask activiti:assignee="${pm}" activiti:exclusive="true" id="_3" name="项目经理审批"/>
    <userTask activiti:assignee="${bm}" activiti:exclusive="true" id="_4" name="部门经理审批"/>
    <endEvent id="_5" name="结束"/>
    <sequenceFlow id="_8" sourceRef="_4" targetRef="_5"/>
    <sequenceFlow id="_6" sourceRef="_2" targetRef="_3"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="_7" name="排他网关"/>
    <sequenceFlow id="_9" sourceRef="_3" targetRef="_7"/>
    <sequenceFlow id="_14" name="&gt;3天" sourceRef="_7" targetRef="_4">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${count > 3}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_15" name="&lt;=3天" sourceRef="_7" targetRef="_5">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${count <= 3}]]></conditionExpression>
    </sequenceFlow>
  </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="230.0" y="45.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <omgdc:Bounds height="55.0" width="85.0" x="200.0" y="125.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <omgdc:Bounds height="55.0" width="85.0" x="200.0" y="340.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="230.0" y="470.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="230.0" y="230.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_15" id="BPMNEdge__15" sourceElement="_7" targetElement="_5">
        <omgdi:waypoint x="262.0" y="246.0"/>
        <omgdi:waypoint x="370.0" y="375.0"/>
        <omgdi:waypoint x="262.0" y="486.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_14" id="BPMNEdge__14" sourceElement="_7" targetElement="_4">
        <omgdi:waypoint x="246.0" y="262.0"/>
        <omgdi:waypoint x="246.0" y="340.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="_2" targetElement="_3">
        <omgdi:waypoint x="246.0" y="77.0"/>
        <omgdi:waypoint x="246.0" y="125.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="246.0" y="395.0"/>
        <omgdi:waypoint x="246.0" y="470.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_3" targetElement="_7">
        <omgdi:waypoint x="246.0" y="180.0"/>
        <omgdi:waypoint x="246.0" y="230.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>

设计图示如下:

4、验证集成工作流是否正常

 编写流程部署的测试类:

    import org.activiti.engine.RepositoryService;
    
     @Autowired
    private RepositoryService repositoryService;
    
    /**
     * 流程部署
     */
    @Test
    public void test() {
        repositoryService.createDeployment()
                .addClasspathResource("bpm/askForLeaveBpm.bpmn")
                .name("请假流程")
                .key("ASK_FOR_LEAVE_ACT")
                .deploy();

        System.out.println("流程部署成功!");
    }

部署成功后,验证已部署的流程:

     @Autowired
    private RepositoryService repositoryService;

	@Test
    public void testQueryInfo() {
        // 查询已部署的流程 -- 请假流程
        DeploymentQuery query = repositoryService.createDeploymentQuery();
        List<Deployment> list = query.deploymentKey("ASK_FOR_LEAVE_ACT").orderByDeploymenTime().desc().list();
        Deployment deployment = list.get(0);
        System.out.println(JSONUtil.toJsonStr(deployment));
        System.out.println("查询成功");
    }

验证结果:

 补充一下,部署bpmn的过程中有出现报错的问题,最后找到报错的原因,是官方提供的内置sql,自动建表完成后,少提供了2个字段,导致部署流程失败,Activiti7官方确实的2个表字段的补充SQL如下:

-- activeti7项目遗留的缺陷

alter table ACT_RE_DEPLOYMENT add column PROJECT_RELEASE_VERSION_ varchar(255);

alter table ACT_RE_DEPLOYMENT add column VERSION_ varchar(255);

请假流程的实体类封装:

package me.zhengjie.modules.activiti.domain.po;


public class ActivitiPO {

    /**
     *
     */
    private String businessKey;

    /**
     * 用户名
     */
    private String userName;


    /**
     * 时间
     */
    private String time;

    /**
     * 请假天数
     */
    private String count;

    /**
     * 项目经理
     */
    private String pm;

    /**
     * 部门经理
     */
    private String bm;

    /**
     * 任务id
     */
    private String taskId;

    /**
     * 审批结果:true 同意, false 拒绝
     */
    private Boolean auditFlag;

    /**
     * 审批信息
     */
    private String message;

    public String getBusinessKey() {
        return businessKey;
    }

    public void setBusinessKey(String businessKey) {
        this.businessKey = businessKey;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getCount() {
        return count;
    }

    public void setCount(String count) {
        this.count = count;
    }

    public String getPm() {
        return pm;
    }

    public void setPm(String pm) {
        this.pm = pm;
    }

    public String getBm() {
        return bm;
    }

    public void setBm(String bm) {
        this.bm = bm;
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public Boolean getAuditFlag() {
        return auditFlag;
    }

    public void setAuditFlag(Boolean auditFlag) {
        this.auditFlag = auditFlag;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

测试发起请假流程:


    @Autowired
    private ILeaveFlowService leaveFlowService;
    
	/**
     * 测试发起请假流程
     */
    @Test
    public void testLaunchWorkFlow() {
        ActivitiPO activitiPo = new ActivitiPO();
        activitiPo.setUserName("test");
        activitiPo.setCount("请假5天,回去结婚");
        activitiPo.setPm("诸葛亮");
        activitiPo.setBm("吴用");
        try {
            leaveFlowService.launchLeaveFlow(activitiPo);
            System.out.println("发起请假流程成功");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("发起请假流程失败");
        }
    }

具体实现逻辑:

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;

@Override
    public void launchLeaveFlow(ActivitiPO activitiPo) {
        // 查询已部署的软件部请假流程
        DeploymentQuery query = repositoryService.createDeploymentQuery();
        List<Deployment> list = query.deploymentKey(WorkFlowDeployKeyEnum.SOFT_DEPARTMENT_LEAVE_FLOW_KEY.key()).orderByDeploymenTime().desc().list();
        Deployment deployment = list.get(0);

        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        List<ProcessDefinition> processList = processDefinitionQuery.deploymentId(deployment.getId()).list();

        // 设置流程执行人
        Map<String, Object> variables = new HashMap<>();
        variables.put("pm", activitiPo.getPm());
        variables.put("bm", activitiPo.getBm());
        variables.put("count", activitiPo.getCount());

        // 设置流程启动者
        Authentication.setAuthenticatedUserId(activitiPo.getUserName());

        // 通过流程部署id启动
        runtimeService.startProcessInstanceById(processList.get(0).getId(), activitiPo.getBusinessKey(), variables);
    }

枚举设计类:

package me.zhengjie.enums;


public enum  WorkFlowDeployKeyEnum {

    SOFT_DEPARTMENT_LEAVE_FLOW_KEY("ASK_FOR_LEAVE_ACT", "请假流程"),
    ;

    private final String key;
    private final String description;

    WorkFlowDeployKeyEnum(String key, String description) {
        this.key = key;
        this.description = description;
    }

    public String key() {
        return key;
    }

    public String description() {
        return description;
    }
}

测试结果:

 

 

5、总结

至此SpringBoot集成Activiti7.0完毕,部署bpmn流程,发起请假流程均能正常使用,不过7.0的相关学习资料还不是很多,遇到好多问题都需要花费一定的时间精力去处理。后续就是对Activiti7.0的相关API的学习,以及和案例结合的一些简单的实践应用。

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。