【工作流引擎】一切需要流转的业务的核心

目录

1.概述

2.环境搭建

3.创建流程

4.操作


1.概述

工作流:

一类能够完全自动执行的过程根据一系列规则,将文档、信息或者任务在不同的执行者之间进行传递和 执行。直白一点说就是业务上一个完整的审批流程,例如员工的入职、请假、出差、采购等等,还有一些关键业务如订单申请、合同审批等等这些过程。

没有工作流之前通常是采用状态字段的方式来跟踪流程的变化情况,例如对于一个员工的请假请求,我们会定义已申请、组长已审核、部门经理已审核等等这样一些状态,然后通过状态来控制不同的业务行为,比如部门经理只能看到组长已经审核通过的并且请假天数不超过3天的订单等等。这种方式有多不方便我想大家写写代码就能感受到了,定的实在太死了,要去扩展或者改动流程就要去该硬编码。

比较好的方式是什么喃?画个流程图,然后程序能自动跟着流程图来跑对吧,流程图可以动态调整。这也就是流程引擎的核心:画一个流程图出来,程序跟着流程图跑,流程图是可以动态扩展的。

市面上开源的工作流引擎很多,本文将会以activiti工作流引擎为例,来带大家感受一下工作流引擎。

先说用什么来画流程图:

BPMN: 一种建模语言,规定了一组符号,很适合拿来描述端到端的业务流程。

activiti使用步骤:

  • 定义流程,即定义.bpmn文件。
  • 部署定义的流程,即使用activiti提供的API把定义的流程存储起来,一般是使用数据库存储。
  • 启动流程实例,即启动一个流程。
  • 用户查询待办任务,流程交给了activiti,用户可以找activiti查询流程的状态。
  • 流程结束,当任务办理完成后没有下一个任务节点的话,这个流程就执行完成了。

2.环境搭建

环境清单:

  • JDK8及以上
  • MySQL
  • IDEA插件:actiBPM,只支持到intellij 2019版本,高版本IDEA需要手动下载安装。

pom依赖:

<properties>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
        </dependency>
        <!-- bpmn 模型处理 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-model</artifactId>
        </dependency>
        <!-- bpmn 转换 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-converter</artifactId>
        </dependency>
        <!-- bpmn json数据转换 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
        </dependency>
        <!-- bpmn 布局 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-layout</artifactId>
        </dependency>
        <!-- mysql驱动 -->
        <!-- 注意和数据库版本对齐,这里我用的mysql8-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!-- 链接池 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- log start -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-dependencies</artifactId>
                <version>7.0.0.Beta1</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

activiti自身的配置文件:

在resource路径下新建配置文件activiti.cfg.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 这里可以使用 链接池 dbcp-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://192.168.31.162:3306/activiti?useSSL=false" />
        <property name="username" value="root" />
        <property name="password" value="admin" />
        <property name="maxActive" value="3" />
        <property name="maxIdle" value="1" />
    </bean>

    <bean id="processEngineConfiguration"
          class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!-- 引用数据源 上面已经设置好了-->
        <property name="dataSource" ref="dataSource" />
        <!-- activiti数据库表处理策略 -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>

log4j配置文件:

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:\activiti\activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n

建库:

和activiti配置文件中的库名对齐。

初始化数据库:

@Test
public void testCreateTable(){
  ProcessEngine processEngine= ProcessEngines.getDefaultProcessEngine();
  System.out.println(processEngine);
}

3.创建流程

一般主要使用以下几个服务来操作工作流:

流程建模:

使用bpmn建模描述好整个流程,配置好每个节点的相关配置。

部署流程:

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("leave.bpmn")
                .name("请假流程")
                .deploy();
        System.out.println("部署流程id:"+deployment.getId());
        System.out.println("部署流程名称:"+deployment.getName());

流程记录:

流程的信息会记录在如下几张表中:

  • act_re_deployment,每个流程的部署信息。
  • act_re_procdef,每个流程的相关信息。
  • act_ge_bytearray,每个流程的详细信息。

4.操作

启动流程:

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //key是bpmn里配置的bpmn文件的id
        ProcessInstance myLeave = runtimeService.startProcessInstanceByKey("myProcess_1");
        System.out.println("实例id:"+myLeave.getId());
        System.out.println("实例name:"+myLeave.getName());

根据用户获取流程列表:

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        List<Task> list = taskService.createTaskQuery().processDefinitionKey("myProcess_1").taskAssignee("worker").list();
        list.forEach((task)->{
            System.out.println(task.getProcessInstanceId());
            System.out.println(task.getId());
            System.out.println(task.getAssignee());
            System.out.println(task.getName());
            //完成,流转到下一个节点
            taskService.complete(task.getId());
        });

获取流程列表:

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        List<Task> list = taskService.createTaskQuery().processDefinitionKey("myProcess_1").orderByProcessDefinitionId().desc().list();
        for (Task task : list) {
            System.out.println(task.getId());
            System.out.println(task.getName());
            System.out.println(task.getProcessInstanceId());
            System.out.println(task.getProcessDefinitionId());
        }

删除流程:

String deploymentId="1";
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //如果该流程中还有未完任务,删除会报错
        repositoryService.deleteDeployment(deploymentId);

查询一个实例的历史信息:

ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId("2501").orderByHistoricActivityInstanceStartTime().asc().list();
        for (HistoricActivityInstance historicActivityInstance : list) {
            System.out.println(historicActivityInstance.getActivityId());
            System.out.println(historicActivityInstance.getActivityName());
        }

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_BugMan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值