zoukankan      html  css  js  c++  java
  • 【知识总结】Activiti工作流学习入门

     1. 我理解的工作流:

       在工作中慢慢接触的业务流程,就向流程控制语言一样,一步一步都对应的不同的业务,但整体串联起来就是一个完整的业务。而且实际工作中尤其是在企业内部系统的研发中,确实需要对应许多审批流程的管理。

      而工作流就是能够在程序中,将这些支离破碎的流程,通过配置的方式管理起来,整体作为一个流程,方便修改,也方便维护。

    2. 什么是Activiti:

      Activiti是一个比较出名的框架,或者说就是一个工作流引擎,通俗的说,就是Activiti引擎我们只要按照它已有的配置,来进行现有业务的对应,它就能够自动帮助我们完成以前不好控制的流程问题。

    3. 如何获取Activiti

      1. 官网通用打包下载:http://www.activiti.org/ 

      3. 源代码github:https://github.com/Activiti/Activiti

      2. maven自行配置:https://git.oschina.net/flyPiglet/ActivitiStudy/      (我的码云、使用git方式可以取得代码)

    3. 如何整合到自己的项目中:

      1. 编程式整合

        

    /** 使用代码创建工作流需要的23张表 */
        @Test
        public void createTable(){
            // 获取流程引擎配置(创建一个单例子的流程引擎)
            ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration
                                                                            .createStandaloneProcessEngineConfiguration();
            // 设置数据库信息
            processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver"); 
            processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/fsop?useUnicode=true&characterEndocing=utf8");
            processEngineConfiguration.setJdbcUsername("root");
            processEngineConfiguration.setJdbcPassword("root");
            /**
             *  processEngineConfiguration 中的配置
             *  DB_SCHEMA_UPDATE_FALSE = "false"; // 不能自动创建表(能够使用脚本创建)
               *    DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop"; // 先删除再更新
             *  DB_SCHEMA_UPDATE_TRUE = "true"; // 如果表不存在我就自动创建表
             */
            // 设置数据库操作的设置
            processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
            // 获取工作流的核心对象
            ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
            Assert.assertNotNull(processEngine);
        }

      2. activit引擎使用独立配置文件

      

    /** 使用配置文件创建流程引擎 */
        @Test
        public void createByConfig(){
            ProcessEngine processEngine = ProcessEngineConfiguration
                                                    .createProcessEngineConfigurationFromResource("activiti.cfg.xml")
                                                    .buildProcessEngine();
            Assert.assertNotNull(processEngine);
        }
    <?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"
      xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
           
        <!-- 创建单例子的流程引擎的配置文件 -->
        <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
            <!-- 链接数据库配置 -->
            <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
            <!-- 转义的话,需要加入& = &amp; -->
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/fsop?useUnicode=true&amp;characterEndocing=utf8"></property>
            <property name="jdbcUsername" value="root"></property>
            <property name="jdbcPassword" value="root"></property>
            <!-- 创建表配置自动创建 -->
            <property name="databaseSchemaUpdate" value="true"></property>
        </bean>
    </beans>

      3. 通过Spring配置文件整合

        其实法2就是Spring的整合方式,说白了Activiti就是提供一个入口,操作数据的25张表,较为规范的完成工作流的实现。

    4. 使用流程介绍:

      1. 流程定义:

        1. 在activiti中流程通过什么方式来管理。

           activiti的流程发布是通过数据库加上配置文件的形式来管理的,而配置文件也是具有版本的,activit会将配置文件存储在数据库的。

          bpmd的标准规范中,流程是具有代码表述以及流程图表述的。所以这两个的资源都会存储在数据库中,以数据库解析出来的资源为准。

        2. 定义使用BPMN的规范定义,也就是用XML来管理。

          生成BPMN的方式主要有三种:Activiti Modeler(activit提供的专门里管理流程文件的war包程序)、Activiti Designer(Eclipse插件,先通过代码生成后,在进行部署工作)

          Activiti Kickstart(基于表格的流程设计工具)上面两个都包含其中

        3. Activit提供Activit Explorer以及Activiti REST等写好的组件来提供方便的后台调用。

        4. 代码:其实流程定义有好几种方式,重点还是能够使用BPMN标准画出符合业务需求的流程图。

      2. 部署流程:

        1. 使用文件部署

        

    /**部署流程定义*/
        @Test
        public void deploymentProcessDefinition_classpath(){
            Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署对象相关的Service
                                .createDeployment() // 创建一个部署对象
                                .name("流程定义") // 设置对应流程的名称
                                .addClasspathResource("diagrams/helloworld.bpmn") // 从Classpath的资源中加载,一次只能加载一个文件(windows与linux下面要区分)
                                .addClasspathResource("diagrams/helloworld.bpmn") // 从Classpath的资源中加载,图片
                                .deploy(); // 完成部署
    
            System.out.println("部署Id:"+deployment.getId()); // 部署Id:20001
            System.out.println("部署名称:"+deployment.getName()); // 部署名称:流程定义
        }

        2. 使用流程定义zip文件部署

    /**部署流程定义zip文件*/
        @Test
        public void deploymentProcessDefinition_zip(){
            InputStream in = this.getClass().getClassLoader().getResourceAsStream("zip/helloworld.zip");
            ZipInputStream zipInputStream = new ZipInputStream(in);
            Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署对象相关的Service
                            .createDeployment() // 创建一个部署对象
                            .name("zip流程定义") // 添加部署的名称
                            .addZipInputStream(zipInputStream) // 制定zip格式文件完成部署
                            .deploy(); // 完成部署
            System.out.println("部署Id:"+deployment.getId()); // 部署Id:22501
            System.out.println("部署名称:"+deployment.getName()); // 部署名称:zip流程定义
        }

       3. 使用输入流部署:

    /**部署流程定义zip文件*/
        @Test
        public void deploymentProcessDefinition_inputStream(){
            InputStream inputStreambpmn = this.getClass().getResourceAsStream("/diagrams/processVariables.bpmn");
            InputStream inputStreampng = this.getClass().getResourceAsStream("/diagrams/processVariables.png");
            
            
            Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署对象相关的Service
                            .createDeployment() // 创建一个部署对象
                            .name("流程定义输入流") // 添加部署的名称
                            .addInputStream("processVariables.bpmn", inputStreambpmn)// 使用资源文件名称(要求与资源文件的名称要一致),和输入流完成部署
                            .addInputStream("processVariables.png", inputStreampng)// 使用资源文件名称(要求与资源文件的名称要一致),和输入流完成部署
                            .deploy(); // 完成部署
            System.out.println("部署Id:"+deployment.getId()); // 部署Id:55001
            System.out.println("部署名称:"+deployment.getName()); // 部署名称:流程定义输入流
        }

      3. 启动流程实例:

        1. 什么是流程实例:就是一个活生生的流程、流程定义是定义了这一类的流程是如何的,而流程实例就是真正的业务流程。一切操作的基础都基于流程实例

        2. 启动流程实例:

    /** 启动流程实例 */
        @Test
        public void startProcessInstance(){
            String processDefinitionKey = "psocessVariables"; // 使用Key的启动,默认按照对心版本的流程定义启动
            ProcessInstance pi = processEngine.getRuntimeService() // 与正在执行的流程实例和执行对象相关的Service
                            .startProcessInstanceByKey(processDefinitionKey); // 使用流程定义的Key启动流程实例,key对应helloworld.bpmn文件中的流程名称
            
            System.out.println("流程实例Id"+pi.getId()); // 流程实例Id:57501
            System.out.println("流程定义Id"+pi.getProcessDefinitionId()); // 流程定义Id:psocessVariables:1:55004
        }

      4. 流程变量:

        1. 流程变量就是对应一个流程下来全局或者局部的变量,可以每个节点都不一样,也可以设置为全局的,这些都通过数据库进行传递

      5. 任务相关:

        1. 任务,流程里面对应很多个任务,通过你画出来的流程图来自动生成任务。 

      6. 整体图:

        

        相关API描述:

        

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
    RuntimeService runtimeService = processEngine.getRuntimeService();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    TaskService taskService = processEngine.getTaskService();
    ManagementService managementService = processEngine.getManagementService();
    IdentityService identityService = processEngine.getIdentityService();
    HistoryService historyService = processEngine.getHistoryService();
    FormService formService = processEngine.getFormService();

    上述所有的都是通过processEngine,所以其实真正想把它用到项目上也是很容易的,只要配置好数据源、数据库表建立好、工作流引擎交由Spring管理,不会影响原先的功能只需要在对应的地方调用API即可。

    5. 数据库表说明:

      其实总共就是23张表、所以使用单元测试进行练习,了解流程原理,入门还是挺容易的。

    #部署对象和流程定义相关表
    #当key值相同的时候版本升级,id未key+版本+随机生成的值
    SELECT * FROM `act_re_deployment`; #部署对象表
    
    SELECT * FROM `act_re_procdef`; #流程定义表`fsop`
    
    SELECT * FROM `act_ge_bytearray`; #资源文件表(一个存储xml,一个存储图片)
    
    SELECT * FROM `act_ge_property`; #逐渐生成策略表(与Id相关)
    
    #####################################################
    #流程实例,执行对象,任务
    SELECT * FROM `act_ru_execution`; #正在执行的执行对象表(正在执行的流程实例)
    
    SELECT * FROM `act_hi_procinst` WHERE `END_TIME_` IS NULL; #流程实例的历史表(一个流程实例)
    
    SELECT * FROM `act_ru_task`; #正在执行的任务表(只有节点是UserTask的才有数据)
    
    SELECT * FROM `act_hi_taskinst`; #任务历史表(只有节点是UserTask的时候该表存在数据)
    
    SELECT * FROM `act_hi_actinst`; #所有活动节点的历史表(其中包括任务也不包括任务)
    #####################################################
    #流程变量
    SELECT * FROM `act_ru_variable`;#正在执行的流程变量表
    
    SELECT * FROM `act_hi_varinst`; #历史流程变量表
    
    ##################################################################
    SELECT * FROM `act_ru_identitylink` #任务表(个人任务、组任务)
    
    SELECT * FROM `act_hi_identitylink` #任务历史表
    
    #########################################################
    SELECT * FROM `act_id_group` #角色表
    
    SELECT * FROM `act_id_user` #用户表
    
    SELECT * FROM `act_id_membership` #用户角色关联表

    6. 相关资料

      由于学习上述的东西,我也是通过别人的视屏来学习,我觉得吧,视屏加手操真的是能够很快上手的呀。

      中文文档Activiti 5.16 中文文档:http://www.mossle.com/docs/activiti/index.html#chapterApi

      百度云:http://pan.baidu.com/s/1gfmdCGj

      学习使用的代码:https://git.oschina.net/flyPiglet/ActivitiStudy/      (我的码云、使用git方式可以取得代码)

    平时上班比较忙,下次做个完整的,哈哈,加油Hikaru!

    微信公众号:努力编程的小猪

    我虽然懒,但是程序员这个职业我还是很喜欢的。

     

  • 相关阅读:
    Python基础语法 第2节课(数据类型转换、运算符、字符串)
    python基础语法 第5节课 ( if 、 for )
    python基础语法 第4节课 (字典 元组 集合)
    Python基础语法 第3节课 (列表)
    A. Peter and Snow Blower 解析(思維、幾何)
    C. Dima and Salad 解析(思維、DP)
    D. Serval and Rooted Tree (樹狀DP)
    C2. Balanced Removals (Harder) (幾何、思維)
    B. Two Fairs 解析(思維、DFS、組合)
    D. Bash and a Tough Math Puzzle 解析(線段樹、數論)
  • 原文地址:https://www.cnblogs.com/fly-piglet/p/6014270.html
Copyright © 2011-2022 走看看