• 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());
            }
        }
    }

  • 相关阅读:
    使用DOM4J生成XML文档的分析和简单实例
    察看数据库索引使用情况
    SQL Server分布式事务模板
    SQLBulkCopy 性能统计
    个人技术发展思路
    在SQLServer 中利用OUTPUT 语句实现删除数据的同时备份数据
    对一段SQL进行语法检查
    LoD 迪米特法则
    开发心得
    实现一个服务的基础结构和管理本地服务和WCF服务的管理器
  • 原文地址:https://www.cnblogs.com/rodge-run/p/6492842.html
Copyright © 2020-2023  润新知