• Activiti:入门


    简介

    工作流(workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的任务,从而实现某个预期的业务目标,或者促使此目标的实现”

    Activiti7概述

    1. .画流程定义模型: 遵守BPMN的流程规范,使用BPMN的流程定义工具,通过 流程符号 把整个业务流程定义出来,可以将流程 定义文件字节流保存到模型数据表中(Model)。
    2. 部署流程定义: 加载画好的流程定义文件,将它转换成流程定义数据(ProcessDefinition),保存到流程定义数据表中。
    3. 启动流程(提交流程申请): 生成流程实例数据(ProcessInstance),生成第1节点任务数据(Task);
    4. 处理人审批流程节点任务: 完成任务审批,生成审批结果,生成下一节点任务数据

    Activiti7环境搭建并创建数据表

    框架版本号:

    springboot 2.5

    Activiti 7.1.0.M6

    Mysql 5.7

    maven依赖:

        <dependencies>
            <!--activiti核心依赖-->
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-engine</artifactId>
                <version>7.1.0.M6</version>
            </dependency>
    
            <!--mysql驱动包-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.23</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.5</version>
            </dependency>
    
            <!-- 日志  -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.26</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>1.7.26</version>
            </dependency>
    
            <!--单元测试-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.6</version>
            </dependency>
        </dependencies>
    

    spring核心配置文件: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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--默认方式下,bean的id必须是processEngineConfiguration -->
        <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
            <!-- 配置数据源 -->
            <property name="jdbcUrl"
                      value="jdbc:mysql://127.0.0.1:3306/activiti01?characterEncoding=utf8&amp;nullCatalogMeansCurrent=true" />
            <property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />
            <property name="jdbcUsername" value="root" />
            <property name="jdbcPassword" value="1234" />
    
            <!-- activiti 数据库表生成策略 -->
            <!--
                自动更新数据库结构
                true:适用开发环境,默认值。activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
                false:适用生产环境。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
                create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
                drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
            -->
            <property name="databaseSchemaUpdate" value="true" />
        </bean>
    
    </beans>
    

    日志文件log4j.properties

    log4j.rootCategory=debug, CONSOLE, LOGFILE
    log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
    
    log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
    log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE.layout.ConversionPattern=%d{HH:mm:ss.SSS} %p [%t] %C.%M(%L) | %m%n
    
    # LOGFILE is set to be a File appender using a PatternLayout.
    log4j.appender.LOGFILE=org.apache.log4j.FileAppender
    log4j.appender.LOGFILE.File=log/activiti-demo01/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
    

    测试方法:

    /**
     * @author wen.jie
     * @date 2022/4/26 15:34
     */
    public class ActivitiTest01 {
        @Test
        public void getProcessEngine() {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            System.out.println(processEngine);
        }
    }
    

    运行结束后,会自动创建一些表:共25个表

    image-20220426160903843

    初始化ProcessEngine源码

      public static ProcessEngine getDefaultProcessEngine() {
        return getProcessEngine(NAME_DEFAULT);
      }
    
      /**
       * obtain a process engine by name.
       * 
       * @param processEngineName
       *          is the name of the process engine or null for the default process engine.
       */
      public static ProcessEngine getProcessEngine(String processEngineName) {
        if (!isInitialized()) {
          init();
        }
        return processEngines.get(processEngineName);
      }
    

    调用init方法:默认情况下加载名为activiti.cfg.xml的文件,然后调用initProcessEngineFromResource方法,去初始化ProcessEngine

    image-20220426162149920

    再看initProcessEngineFromResource方法:调用了buildProcessEngine方法创建ProcessEngine

    image-20220426162351255

    再进入buildProcessEngine方法:将文件转成流,再调用ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream)返回ProcessEngineConfiguration,去创建ProcessEngine

      private static ProcessEngine buildProcessEngine(URL resource) {
        InputStream inputStream = null;
        try {
          inputStream = resource.openStream();
          ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream);
          return processEngineConfiguration.buildProcessEngine();
    
        } catch (IOException e) {
          throw new ActivitiIllegalArgumentException("couldn't open resource stream: " + e.getMessage(), e);
        } finally {
          IoUtil.closeSilently(inputStream);
        }
      }
    

    createProcessEngineConfigurationFromInputStream方法:最终调用BeansConfigurationHelper去创建,并且传参beanName=processEngineConfiguration

    image-20220426162618734

    再看BeansConfigurationHelper

    public class BeansConfigurationHelper {
    
      public static ProcessEngineConfiguration parseProcessEngineConfiguration(Resource springResource, String beanName) {
          //创建beanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
          //读取xml配置文件
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        xmlBeanDefinitionReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);
        xmlBeanDefinitionReader.loadBeanDefinitions(springResource);
          //从beanFactory中去找到名为processEngineConfiguration的bean
        ProcessEngineConfigurationImpl processEngineConfiguration = (ProcessEngineConfigurationImpl) beanFactory.getBean(beanName);
          //把beanFactory设置到processEngineConfiguration中并返回
        processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(beanFactory));
        return processEngineConfiguration;
      }
    
      public static ProcessEngineConfiguration parseProcessEngineConfigurationFromInputStream(InputStream inputStream, String beanName) {
        Resource springResource = new InputStreamResource(inputStream);
        return parseProcessEngineConfiguration(springResource, beanName);
      }
    
      public static ProcessEngineConfiguration parseProcessEngineConfigurationFromResource(String resource, String beanName) {
        Resource springResource = new ClassPathResource(resource);
        return parseProcessEngineConfiguration(springResource, beanName);
      }
    
    }
    

    自定义配置文件和bean名称

    我这里创建了activiti.cfg2.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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--默认方式下,bean的id必须是processEngineConfiguration -->
        <bean id="myProcessEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
            <!-- 配置数据源 -->
            <property name="jdbcUrl"
                      value="jdbc:mysql://127.0.0.1:3306/activiti01?characterEncoding=utf8&amp;nullCatalogMeansCurrent=true" />
            <property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />
            <property name="jdbcUsername" value="root" />
            <property name="jdbcPassword" value="1234" />
    
            <!-- activiti 数据库表生成策略 -->
            <!--
                自动更新数据库结构
                true:适用开发环境,默认值。activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
                false:适用生产环境。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
                create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
                drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
            -->
            <property name="databaseSchemaUpdate" value="true" />
        </bean>
    
    </beans>
    

    测试:

        @Test
        public void getProcessEngine2() {
            //经过上面读源码的过程后,也能自定义配置文件和bean名称
            ProcessEngineConfiguration engineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg2.xml", "myProcessEngineConfiguration");
            ProcessEngine processEngine = engineConfiguration.buildProcessEngine();
            System.out.println(processEngine);
        }
    

    同样也能创建ProcessEngine:

    image-20220426163256210

    25张表的含义

    Acitiviti数据库中表的命名都是以 ACT_ 开头的。

    第二部分是一个两个字符用例表的标识。此用例大体与服务API是 匹配的。

    ACT_GE_* : GE 表示 general 。通用数据,各种情况都使用的数据 ,如存放资源文件(图片,规则等)。

    ACT_HI_xxx : HI 表示history。就是这些表包含着历史的相关数据,如结束的流程实例(变量,任务等)。

    ACT_RE_xxx : RE 表示repository。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则 等)。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。

    ACT_RU_xxx : RU 表示 runtime。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的 数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。

    ACT_EVT_* :EVT表示EVENT,流程引擎的通用事件日志记录表,方便管理员跟踪处理。

    表分类 表名 说明
    通用数据
    act_ge_bytearray 二进制数据表(流程图)
    act_ge_property 属性数据表,存储整个流程引擎级别的数据,初始化表结构时,会 插入版本号信息等
    历史数据
    act_hi_actinst 历史节点表
    act_hi_attachment 历史附件表
    act_hi_comment 历史意见表
    act_hi_detail 历史详情表,提供历史变量的查询
    act_hi_identitylink 历史流程人员表,主要存储任务节点与参与者的相关信息
    act_hi_procinst 历史流程实例表
    act_hi_taskinst 历史任务实例表
    act_hi_varinst 历史变量表
    流程定义表
    act_re_deployment 部署信息表
    act_re_model 流程设计模型表
    act_re_procdef 流程定义数据表
    流程运行数据表
    act_ru_deadletter_job 作业死亡信息表,如果作业失败超过重试次数,则写入到此表
    act_ru_event_subscr throwEvent、catchEvent时间监听信息表
    act_ru_execution 运行时流程执行实例表
    act_ru_identitylink 运行时流程人员表,主要存储任务节点与参与者的相关信息
    act_ru_integration 运行时积分表
    act_ru_job 定时异步任务数据表
    act_ru_suspended_job 运行时作业暂停表, 比如流程中有一个定时任务,如果把这个任 务停止工作了,这个任务写入到此表中
    act_ru_task 运行时任务节点表
    act_ru_timer_job 运行时定时器作业表
    act_ru_variable 运行时流程变量数据表
    其他表
    act_procdef_info 流程定义的动态变更信息
    act_evt_log 流程引擎的通用事件日志记录表
    1. Activiti 7的M4以上版本,部署流程定义时,报错如下:

      报错: MySQLSyntaxErrorException: Unknown column 'VERSION_' in 'field list'

      解决:因为 ACT_RE_DEPLOYMENT 表缺少 VERSION和 PROJECT_RELEASE_VERSION_ 字段,执行以下语句 添加

    ALTER TABLE ACT_RE_DEPLOYMENT ADD COLUMN VERSION_ VARCHAR(255);
    ALTER TABLE ACT_RE_DEPLOYMENT ADD COLUMN PROJECT_RELEASE_VERSION_ VARCHAR(255);
    

    在 Activiti7.1.0.M6已经有了这些,不用执行上面sql。

    Activiti API 服务接口

    Activiti 流程引擎包含了25张表,而且表之间的关系也比较复杂,比如包含各种外键约束。

    按照传统的方式,有了数据库表后,就应该为每张表创建 Entity 实体类,然后为其创建对应的 DAO 接口,然 后再创建对应的 Service来实现对表数据的增删改查;

    但是按照传统方式的,就会有一个很严峻的问题,表的数量太多,并且关系复杂,还要兼顾流程引擎的处理方 式,自己去搞一套,几乎不可能;

    其实不需要我们去创建Entity 、 DAO、Service、Controller,因为Activiti已经把这些东西给搞好了,只需要 调用即可。

    Process Engine API 和服务

    引擎 API 是与 Activiti 交互的最常见方式。

    您可以从ProcessEngine中获取包含工作流/ BPM方法的各种服务。

    ProcessEngine和服务对象是线程安全的。因此,您可以为整个服务器保留对其中之一的引用。

    Service 是工作流引擎提供用于进行工作流部署、执行、管理的服务接口,我们使用对应Service接口可以操作对应的数据表。

    image-20220428102902490

    注意:activiti 7 没有IdentityService和FormService接口

    Activiti7 的Servcie核心接口

    1. Service 管理接口说明
    Service接口 说明
    RuntimeService 运行时 Service,可以处理所有正在运行状态的流程实例和任务等
    RepositoryService 流程仓库 Service,主要用于管理流程仓库,比如流程定义的控制管理(部署、删除、挂起、激活....)
    ManagementService 引擎管理Service,和具体业务无关,主要用于对Activiti流程引擎的管理和维护
    DynamicBpmnService RepositoryService可以用来部署流程定义(使用xml形式定义好的),一旦部署到Activiti(解析后保存到DB),那么流程定义就不会再变了,除了修改 xml定义文件内容;而DynamicBpmnService就允许我们在程序运行过程中去修改流程定义,例如:修改流程定义中的分配角色、优先级、流程流转的 条件...
    TaskService 任务 Service,用于管理和查询任务,例如:签收、办理等
    HistoryService 历史 Service,可以查询所有历史数据,例如:流程实例信息、参与者信息、完成时间....
    1. 核心 Service 接口实例获取方式如下:
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            RuntimeService runtimeService = processEngine.getRuntimeService();
            RepositoryService repositoryService = processEngine.getRepositoryService();
            ManagementService managementService = processEngine.getManagementService();
            DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();
            TaskService taskService = processEngine.getTaskService();
            HistoryService historyService = processEngine.getHistoryService();
    
  • 相关阅读:
    最大熵模型
    python安装深度学习包theano,Pylearn2,scikit-neuralnetwork
    sklearn之learningcurve
    sklearn之validationcurve
    SVM
    一年7篇CVPR和4篇ICCV——女神
    CUDA大作业_进行图像特征匹配V2.0
    CUDA大作业_进行图像特征匹配V1.0
    从K近邻算法、距离度量谈到KD树、SIFT+BBF算法
    Ubuntu 开机出现 grub rescue> 终端模式修复方法
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/16201922.html
Copyright © 2020-2023  润新知