zoukankan      html  css  js  c++  java
  • activiti工作流框架简介

    常见的工作流框架:activiti, JBPM, OSWorkflow

    activiti框架基于23张基础的表数据, 基于Mybatis操作数据库.

    JBPM框架基于18张基础的表数据, 基于hibernate操作数据库.

    一. activiti基础数据表的创建

    1.通过sql创建

    导入activiti-5.13databasecreate目录下的sql建表语句, 如果数据库是mysql, 则需要导入activiti.mysql.create.engine.sql, activiti.mysql.create.history.sql, activiti.mysql.create.identity.sql三张表;

    2.通过java代码创建

    2.1 在不提供xml配置文件的情况下

      //通过在java中创建流程引擎配置对象来创activiti的基础表数据
        @Test
        public void demo1 () {
            //创建流程引擎配置对象
            ProcessEngineConfiguration configuration =
                    ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
            configuration.setJdbcDriver("com.mysql.jdbc.Driver");
            configuration.setJdbcUrl("jdbc:mysql://localhost:3306/activiti_demo");
            configuration.setJdbcUsername("root");
            configuration.setJdbcPassword("123");
            //设置自动建表
            configuration.setDatabaseSchemaUpdate("true");
            //创建流程引擎对象, 在创建流程引擎对象时会自动建表
            ProcessEngine buildProcessEngine = configuration.buildProcessEngine();
        }

    2.2 提供xml配置文件

    1.配置文件位于src根路径下, 名称为activiti-context.xml

        <!-- 配置一个流程引擎配置对象 -->
        <bean id="processEngineConfiguration"
            class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
            <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti_demo"></property>
            <property name="jdbcUsername" value="root"></property>
            <property name="jdbcPassword" value="luoji1025"></property>
            <property name="databaseSchemaUpdate" value="true"></property>
        </bean>
        
        <!-- 配置一个流程引擎工厂bean用于创建流程引擎配置对象 -->
        <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
            <property name="processEngineConfiguration" ref="processEngineConfiguration"></property>
        </bean>
    </beans>

    2.Java代码

         //通过配置文件结合java代码实现activiti基础表的创建
        @Test
        public void demo2() {
            //通过配置文件,创建流程引擎配置对象
            ProcessEngineConfiguration configuration = ProcessEngineConfiguration.
                    createProcessEngineConfigurationFromResource("activiti-context.xml", "processEngineConfiguration");
            ProcessEngine processEngine = configuration.buildProcessEngine();
        }

     2.3 使用默认的配置文件(推荐使用)

      要求配置文件必须在类路径的根路径下,配置文件的名称必须为activiti-context.xml或者为activiti.cfg.xml,xml配置文件中必须配置流程引擎配置对象id必须为processEngineConfiguration,必须配置流程引擎工厂bean,id必须为processEngine(具体配置与上面的xml一致)

         //通过默认的配置文件创建activiti基础表
        @Test
        public void demo3 () {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        }

    二. activiti中23张表的介绍

    Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。

    1)      ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。

    2)      ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。

    3)      ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,比如用户,组等等。

    4)      ACT_HI_*: 'HI'表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。

    ACT_GE_*: 通用数据, 用于不同场景下。

      业务流程建模与标注(Business Process Model and Notation,BPMN) ,描述流程的基本符号,包括这些图元如何组合成一个业务流程图(Business Process Diagram)

     三. activiti中常用的对象

    3.1 几个和流程相关的对象

    Deployment:部署对象,和部署表对应act_re_deployment

    ProcessDefinition:流程定义对象,和流程定义表对应act_re_procdef

    ProcessInstance:流程实例对象,和流程实例表对应act_ru_execution

    Task:任务对象,和任务表对应act_ru_task

    3.2 几个Service对象

    RepositoryService:操作部署、流程定义等静态资源信息

    RuntimeService:操作流程实例,启动流程实例、查询流程实例、删除流程实例等动态信息

    TaskService:操作任务,查询任务、办理任务等和任务相关的信息

    HistoryService:操作历史信息的,查询历史信息

    IdentityService:操作用户和组

    3.3  几个Query对象

    DeploymentQuery:对应查询部署表act_re_deployment

    ProcessDefinitionQuery:对应查询流程定义表act_re_procdef

    ProcessInstanceQuery:对应查询流程实例表act_ru_execution

    TaskQuery:对应查询任务表act_ru_task

     四. Activiti流程定义框架中常用的API

     4.1 部署与流程定义相关的API

    4.1.1 部署流程定义

    1>基于元数据(bpmn和png)文件创建

     /*
         * 部署流程定义
         * 影响的表
         * 1.act_re_deployment:部署表
         * 2.act_re_procdef:流程定义表(流程部署后,会在流程定义表中创建一个流程定义对象)
         * 3.act_ge_bytearray:二进制表(保存bpmn和png文件)
         */

     private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        @Test
        public void demo4 () {
            //创建一个部署构建器对象, 用于加载制定的文件
            DeploymentBuilder deployment = processEngine.getRepositoryService().createDeployment();
            deployment.addClasspathResource("qjlc.bpmn");
            deployment.addClasspathResource("qjlc.png");
            //部署,返回部署对象
            Deployment deploy = deployment.deploy();
            System.out.println(deploy.getId());
        }

    2> 基于bpmn和png文件的压缩文件创建

    @Test
        public void demo1 () {
            //获取文件部署构建器对象
            DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
            //2.通过zip文件部署(常用)
            ZipInputStream zipInputStream = new ZipInputStream(this.getClass().getClassLoader()
                    .getResourceAsStream("qjlc.zip"));
            deploymentBuilder.addZipInputStream(zipInputStream);
            Deployment deploy = deploymentBuilder.deploy();
            System.out.println(deploy.getId());
        }

     4.1.2 查询部署信息

        @Test
        public void demo2 () {
            DeploymentQuery query = processEngine.getRepositoryService().createDeploymentQuery();
    //        query.deploymentId("701");
            List<Deployment> list = query.list();
            for (Deployment deployment : list) {
                System.out.println(deployment.getId() + " " + deployment.getName());
            }
        }

     4.1.3 删除部署信息

        /*
         * 删除部署信息
         */
        @Test
        public void demo3 () {
            String deploymentId = "601";
            boolean cascade = false;
            processEngine.getRepositoryService().deleteDeployment(deploymentId, cascade);
        }

     4.1.4 查询流程定义

     /*
         * 查询流程定义
         * 操作的数据表:act_re_procdef流程定义表
         */
        @Test
        public void demo5 () {
            //获取流程定义查询对象
            ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
            //根据流程定义的key进行过滤
            query.processDefinitionKey("qjlc");
            //添加排序条件
            query.orderByProcessDefinitionVersion().desc();

       //查询最新的版本

       query.latestVersion();
            //查询
            List<ProcessDefinition> list = query.list();
            for (ProcessDefinition definition : list) {
                System.out.println(definition.getId() + " " + definition.getKey() + " " + definition.getName());
            }
        }

    4.1.5 查询一次部署对应的流程部署文件名称和输入流 

       @Test
        public void demo5 () {
            String deploymentId = "1";
            List<String> names = processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId);
            for (String name : names) {
                System.out.println(name);
                InputStream inputStream = processEngine.getRepositoryService().getResourceAsStream(deploymentId, name);
                try {
                    FileUtils.copyInputStreamToFile(inputStream, new File("E:\"+name));
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    4.1.6 获取文件名称和输入流

        @Test
        public void demo6 () throws IOException {
            //获取流程定义的id
            String processDefinitionId = "qjlc:4:904";
            //获取流程定义查询对象
            ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
            //根据id进行查询
            query.processDefinitionId(processDefinitionId);
            //调整查询结果集
            ProcessDefinition processDefinition = query.singleResult();
            //根据流程定义对象获取png图片的名称
            String name = processDefinition.getDiagramResourceName();
            //获取png图片对应的输入流
            InputStream inputStream = processEngine.getRepositoryService().getProcessDiagram(processDefinitionId);
            //调用fileutils工具类查询数据
            FileUtils.copyInputStreamToFile(inputStream, new File("e:\"+name));
            inputStream.close();
        }

     4.2 流程定义实例和任务相关的API

     4.2.1 启动流程定义实例

      /*
         * 启动流程实例
         * 操作的数据表:
         * 1.act_ru_execution:流程实例表
         * 2.act_ru_task:任务表(启动流程实例时,会在任务表中创建一个任务)
         */
        @Test
        public void demo6 () {
            //流程定义的id
            String processId = "qjlc:1:4";
            //通过runtimeservice启动流程实例
            ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processId);
            System.out.println(processInstance.getId() + "  " + processInstance.getBusinessKey() + "  " + processInstance.getParentId());    
        }

    4.2.2 查询流程实例

        @Test
        public void demo8 () {
            ProcessInstanceQuery query = processEngine.getRuntimeService().createProcessInstanceQuery();
            List<ProcessInstance> list = query.list();
            for (ProcessInstance processInstance : list) {
                System.out.println(processInstance.getId() + " " + processInstance.getActivityId());
            }
            //查询任务
            TaskQuery query2 = processEngine.getTaskService().createTaskQuery();
            List<Task> list2 = query2.list();
            for (Task task : list2) {
                System.out.println(task.getId() + "  " + task.getName());
            }
        }

     4.2.3 查询任务

         /*
         * 查询任务
         */
        @Test
        public void demo7 () {
            TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery();
            taskQuery.taskAssignee("王五");
            List<Task> list = taskQuery.list();
            for (Task task : list) {
                System.out.println(task.getId() + "  " + task.getName());
            }
        }

     4.2.4 办理任务

         /*
         * 办理任务
         */
        @Test
        public void demo8 () {
            String taskId = "402";
            processEngine.getTaskService().complete(taskId);
        }

    五. 流程变量

    5.1流程变量的创建

    流程变量的创建有四种方式:创建流程实例时创建, 办理任务时创建, 基于runtimeservice创建, 基于taskservice创建

    5.1.1 当流程实例启动时设置流程变量

         @Test
        public void demo2 () {
            String processDefinitionId = "qjlc:5:1604";
            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("key1", "value1");
            variables.put("key2", "value2");
            ProcessInstance  processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinitionId, variables);
            System.out.println(processInstance.getId());
        }

     5.1.2 在办理任务时创建

         @Test
        public void demo3 () {
            TaskService taskService = processEngine.getTaskService();
            TaskQuery taskQuery = taskService.createTaskQuery();
            List<Task> list = taskQuery.list();
            for (Task task : list) {
                System.out.println(task.getId());
                String taskId = task.getId();
                Map<String, Object> variables = new HashMap<String, Object>();
                variables.put("k1", "v1");
                variables.put("k2", "v2");
                taskService.complete(taskId, variables);
            }
            
        }

    5.1.3 利用runtimeservice创建流程变量

         @Test
        public void demo4 () {
            String executionId = "1701";
            String variableName = "qjyy";
            Object value = "想请假了!";
            //创建单个流程变量
            processEngine.getRuntimeService().setVariable(executionId, variableName, value);
            //创建多个流程变量
            Map<String, Object> variables = new HashMap<>();
            variables.put("k3", "v3");
            variables.put("k4", "v4");
            processEngine.getRuntimeService().setVariables(executionId, variables);
        }

    5.1.4 利用taskservice创建流程变量

         @Test
        public void demo5 () {
            String taskId = "1804";
            String variableName = "qjts";
            Object value = 7;
            //创建单个流程变量
            processEngine.getTaskService().setVariable(taskId, variableName, value);
            //创建多个流程对象
            Map<String, Object> variables = new HashMap<>();
            variables.put("k5", "v5");
            variables.put("k6", "v6");
            processEngine.getTaskService().setVariables(taskId, variables);
        }

     5.1.5 流程变量中存放自定义对象(自定义对象要实现Serializable接口)

         @Test
        public void demo5_1 () {
            //创建流程实例
            /*String processDefinitionKey = "qjlc";
            ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey );
            System.out.println(processInstance.getId());*/
            //创建流程变量
            String executionId = "2501";
            Map<String, Object> variables = new HashMap<>();
            User user = new User();
            user.setUsername("老王");
            user.setPassword("123");
            variables.put("user", user );
            processEngine.getRuntimeService().setVariables(executionId , variables);
        }

    自定义对象User

    package cn.rodge.activiti.variable;
    import java.io.Serializable;
    public class User implements Serializable {
        private static final long serialVersionUID = 1L;
        private String username;
        private String password;
        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;
        }
    }

     5.2 流程变量的获取

     5.2.1 基于RuntimeService获取

         @Test
        public void demo6 () {
            String executionId = "1701";
            String variableName = "qjts";
            //获取单个流程变量
            Object variable = processEngine.getRuntimeService().getVariable(executionId, variableName);
            System.out.println(variable);
            //获取多个流程变量
            Map<String, Object> variables = processEngine.getRuntimeService().getVariables(executionId);
            System.out.println(variables);
        }

     5.2.2 基于TaskService获取

        @Test
        public void demo7 () {
            String taskId = "1804";
            String variableName = "qjyy";
            //获取单个流程变量
            Object variable = processEngine.getTaskService().getVariable(taskId, variableName);
            System.out.println(variable);
            Object getVariables;
            //获取多个流程变量, 获取当前流程所在流程实例中的所有流程变量
            Map<String, Object> variables = processEngine.getTaskService().getVariables(taskId);
            System.out.println(variables);
        }

     六. 组任务

    6.1 候选人组任务

     

    6.1.1 查询组任务

        @Test
        public void demo5 () {
            TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery();
            taskQuery.taskCandidateUser("李四");
            List<Task> list = taskQuery.list();
            for (Task task : list) {
                System.out.println(task.getId() + "  " + task.getName());
            }
        }

    6.1.2 拾取组任务

        @Test
        public void demo6 () {
            String taskId = "3802";
            String userId = "李四";
            processEngine.getTaskService().claim(taskId, userId);
        }

     6.1.3 退回组任务

         @Test
        public void demo7 () {
            String taskId = "3802";
            String userId = null;
            processEngine.getTaskService().setAssignee(taskId, userId);
        }

     6.2 候选组组任务

     

    6.2.1 创建组

            @Test
            public void demo3 () {
                Group group = new GroupEntity();
                group.setId("财务人员组");
                group.setName("财务人员组");
                processEngine.getIdentityService().saveGroup(group);
            }

    6.2.2 创建用户

        @Test
        public void demo4 () {
            User user = new UserEntity();
            user.setId("002");
            user.setFirstName("小明");
            processEngine.getIdentityService().saveUser(user);
        }

    6.2.3 将用户添加到组

        @Test
        public void demo5 () {
            String groupId = "财务人员组";
            String userId = "002";
            processEngine.getIdentityService().createMembership(userId, groupId);
        }

    6.2.4 查询组任务

        @Test
        public void demo8 () {
            TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery();
            taskQuery.taskCandidateUser("002");
            List<Task> list = taskQuery.list();
            for (Task task : list) {
                System.out.println(task.getId() + " " + task.getName());
            }
        }

    6.2.5 拾取组任务

        @Test
        public void demo9 () {
            String userId = "002";
            String taskId = "4702";
            processEngine.getTaskService().claim(taskId, userId);
        }

    拾取完组任务后,就可以按照正常的任务办理流程办理任务了

    6.2.6 退回组任务

         @Test
        public void demo10 () {
            String userId = null;
            String taskId = "4702";
            processEngine.getTaskService().setAssignee(taskId, userId);
        }

     七. 网关(排他网关)

     

     private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        /*
         * 部署流程
         */
        @Test
        public void demo1() {
            DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
            deploymentBuilder.addClasspathResource("cn/rodge/activiti/gatewall/bxlcnew.bpmn");
            deploymentBuilder.addClasspathResource("cn/rodge/activiti/gatewall/bxlcnew.png");
            Deployment deploy = deploymentBuilder.deploy();
            System.out.println(deploy.getId());
        }

        /*
         * 创建流程实例
         */
        @Test
        public void demo2() {
            String processDefinitionKey = "cwlc";
            ProcessInstance processInstance = processEngine.getRuntimeService()
                    .startProcessInstanceByKey(processDefinitionKey);
            System.out.println(processInstance.getId());
        }

        /*
         * 查询流程实例
         */
        @Test
        public void demo3() {
            ProcessInstanceQuery processInstanceQuery = processEngine.getRuntimeService().createProcessInstanceQuery();
            List<ProcessInstance> list = processInstanceQuery.list();
            for (ProcessInstance processInstance : list) {
                System.out.println(processInstance.getId() + "  " + processInstance.getActivityId());
            }
        }
        /*
         * 查询任务
         */
        @Test
        public void demo4 () {
            TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery();
            taskQuery.taskAssignee("王五");
            List<Task> list = taskQuery.list();
            for (Task task : list) {
                System.out.println(task.getId() + "  " + task.getAssignee());
            }
        }
        /*
         * 执行任务同时创建变量bxje
         */
        @Test
        public void demo5 () {
            String taskId = "6004";
            Map<String, Object> variables = new HashMap<>();
            variables.put("bxje", 2000);
            processEngine.getTaskService().complete(taskId, variables);
        }

     当定义的流程变量bxje>1000时, 就会执行"财务主管审批"的分支

     八. spring整合activiti

    第一步:提供spring配置文件,配置数据源、事务管理器、spring提供的流程引擎配置对象、流程引擎工厂bean

     <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        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
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-2.5.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
        <!-- 配置数据源 -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://localhost:3306/activiti_demo"></property>
            <property name="username" value="root"></property>
            <property name="password" value="luoji1025"></property>
        </bean>
        <!-- 配置事务管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 配置一个Spring整合流程引擎配置对象 -->
        <bean id="processEngineConfiguration"
            class="org.activiti.spring.SpringProcessEngineConfiguration">
            <!-- 配置数据源 -->
            <property name="dataSource" ref="dataSource"></property>
            <!-- 配置事务 -->
            <property name="transactionManager" ref="transactionManager"></property>
            <!-- 配置自动activiti的自动建表 -->
            <property name="databaseSchemaUpdate" value="true"></property>
        </bean>
        
        <!-- 配置一个流程引擎工厂bean用于创建流程引擎配置对象 -->
        <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
            <property name="processEngineConfiguration" ref="processEngineConfiguration"></property>
        </bean>
    </beans>

     java代码

    public class ActivitiSpring {
        public static void main(String[] args) {
            // 获取配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            // 从配置文件中获取流程引擎对象
            ProcessEngine processEngine = (ProcessEngine) context.getBean("processEngine");
            ProcessDefinitionQuery definitionQuery = processEngine.getRepositoryService().createProcessDefinitionQuery();
            List<ProcessDefinition> list = definitionQuery.list();
            for (ProcessDefinition processDefinition : list) {
                System.out.println(processDefinition.getId() + "  " + processDefinition.getName());
            }
        }
    }

  • 相关阅读:
    NanoProfiler
    NanoProfiler
    Open Source Cassandra Gitbook for Developer
    Android Fragment使用(四) Toolbar使用及Fragment中的Toolbar处理
    Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复
    Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误
    Android Fragment使用(一) 基础篇 温故知新
    Set up Github Pages with Hexo, migrating from Jekyll
    EventBus源码解析 源码阅读记录
    Android M Permission 运行时权限 学习笔记
  • 原文地址:https://www.cnblogs.com/rodge-run/p/6492842.html
Copyright © 2011-2022 走看看