Activiti学习笔记四

本文详细介绍了使用Activiti流程引擎进行流程设计与实现的具体步骤,包括流程部署、启动、任务查询与完成,以及如何利用流程变量控制流程走向。涵盖了排他网关、并行网关、接收活动等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

连线

流程图绘制
连线

condition:为流程变量的设置

路程部署

/**
     * 部署流程
     */
    private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
    @Test
    public void deployProcess(){
        //得到RepositoryService
        RepositoryService service = processEngine.getRepositoryService();
        //部署
        InputStream isBpmn = this.getClass().getResourceAsStream("/SequenceFlow.xml");
        InputStream isPng = this.getClass().getResourceAsStream("/SequenceFlow.png");
        Deployment deployment = service.createDeployment().name("连线")//部署的名称
                .addInputStream("SequenceFlow.bpmn", isBpmn)//设置;流程图的xml文件
                .addInputStream("SequenceFlow.png", isPng)//设置流程图的PNG文件
                .deploy();//确定
        /**
         * act_re_deployment:流程部署表
         * act_re_model:
         * act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
         * act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
         * act_ge_property:系统内置表存放activiti的版本和自动增长的字段
         */

        System.out.println("流程部署成功:");
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名称:" + deployment.getName());
        System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
    }

流程启动

    /**
     * 启动流程
     */
    @Test
    public void startProcess(){

        /**
         * act_ru_execution:流程实例ID,里面有流动ID,流程定义ID
         * act_ru_identitylink:当前流程节点的办理人信息
         * act_ru_task:当前正在执行的流程任务表
         * act_ru_variable:执行的流程变量
         */

        //得到流程运行服务
        RuntimeService runtimeService = this.processEngine.getRuntimeService();
        //启动流程、
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("SequenceFlow");
        System.out.println("流程启动成功");
        System.out.println("流程实例ID:" + processInstance.getId());
    }

查询个人任务

    /**
     * 查询个人任务
     */
    @Test
    public void findUserTask(){
        //任务办理人
        String assignee = "王五";
        //得到任务的Service
        TaskService taskService = this.processEngine.getTaskService();
        //创建一个查询
        List<Task> list = taskService.createTaskQuery().taskId("15005").list();
        for(Task task : list){
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务办理人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getExecutionId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("流程定义ID:" + task.getProcessDefinitionId());
            System.out.println("流程:" + task.getProcessInstanceId());
            System.out.println("任务创建时间:" + task.getCreateTime());
        }
    }

使用流程变量完成任务(重要)

    /**
     * 使用流程变量完成任务
     */
    @Test
    public void completeTaskWithVariables(){
        String taskId = "15005";
        //得到任务的Service
        TaskService taskService = this.processEngine.getTaskService();
        Map<String,Object> variables = new HashMap<>();
        variables.put("message","重要");
        //通过流程变量控制连线的走向
        taskService.complete(taskId,variables);
        System.out.println("任务完成");
    }

完成任务

   /**
     * 完成任务
     */
    @Test
    public void completeTask(){
        String taskId = "17503";
        //得到任务的Service
        TaskService taskService = this.processEngine.getTaskService();
        //通过流程变量控制连线的走向
        taskService.complete(taskId);
        System.out.println("任务完成");
    }

总结:

1、一个活动中可以指定一个或多个SequenceFlow(Start中有一个,End中没有)

  • 开始活动中有一个SequenceFlow
  • 结束活动中没有SequenceFlow
  • 其他活动中有1条或多条SequenceFlow

2、如果只有一个,则可以不使用流程变量设置codition的名称

如果有多个,则需要使用流程变量设置codition的名称,message表示流程变量名称,'不重要’表示流程变量的值,${}中间的内容要使用boolean类型的表达式,用来判断应该执行的连线

排他网关(ExclusiveGateWay)

报销

业务员提交报销申请

如果金额小于500 可以直接由财务审批

如果金额大于等于500 小于1000由部门经理审批

如果金额大于等于1000 由总经理审批

流程图

排他网关

其中boolean表达式使用和连线中相似

默认的流程无须设定,我被坑了

流程部署

/**
     * 部署流程
     */
    private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
    @Test
    public void deployProcess(){
        //得到RepositoryService
        RepositoryService service = processEngine.getRepositoryService();
        //部署
        InputStream isBpmn = this.getClass().getResourceAsStream("/ExclusiveGateWay.xml");
        InputStream isPng = this.getClass().getResourceAsStream("/ExclusiveGateWay.png");
        Deployment deployment = service.createDeployment().name("排他网关")//部署的名称
                .addInputStream("ExclusiveGateWay.bpmn", isBpmn)//设置;流程图的xml文件
                .addInputStream("ExclusiveGateWay.png", isPng)//设置流程图的PNG文件
                .deploy();//确定
        /**
         * act_re_deployment:流程部署表
         * act_re_model:
         * act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
         * act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
         * act_ge_property:系统内置表存放activiti的版本和自动增长的字段
         */

        System.out.println("流程部署成功:");
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名称:" + deployment.getName());
        System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
    }

启动流程(变量设置)

    /**
     * 启动流程
     */
    @Test
    public void startProcess(){

        /**
         * act_ru_execution:流程实例ID,里面有流动ID,流程定义ID
         * act_ru_identitylink:当前流程节点的办理人信息
         * act_ru_task:当前正在执行的流程任务表
         * act_ru_variable:执行的流程变量
         */

        //得到流程运行服务
        RuntimeService runtimeService = this.processEngine.getRuntimeService();
        //启动流程 需要给出排他网关的条件
        Map<String,Object> variables = new HashMap<>();
        variables.put("money",1200);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ExclusiveGateWay",variables);
        System.out.println("流程启动成功");
        System.out.println("流程实例ID:" + processInstance.getId());
    }

查询个人任务

/**
     * 查询个人任务
     */
    @Test
    public void findUserTask(){
        //任务办理人
        String assignee = "王五";
        //得到任务的Service
        TaskService taskService = this.processEngine.getTaskService();
        //创建一个查询
        List<Task> list = taskService.createTaskQuery().taskId("2507").list();
        for(Task task : list){
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务办理人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getExecutionId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("流程定义ID:" + task.getProcessDefinitionId());
            System.out.println("流程:" + task.getProcessInstanceId());
            System.out.println("任务创建时间:" + task.getCreateTime());
        }
    }

完成任务

    /**
     * 完成任务
     */
    @Test
    public void completeTask(){
        String taskId = "2507";
        //得到任务的Service
        TaskService taskService = this.processEngine.getTaskService();
        //通过流程变量控制连线的走向
        taskService.complete(taskId);
        System.out.println("任务完成");
    }

总结:

  • 一个排他网关对应一个以上的顺序流
  • 由排他网关流出的顺序流都有个coditionExpression元素,在内部维护返回boolean类型的决策结果
  • 决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出
  • 如果没有任何一个出口符合条件,则抛出异常
  • 使用流程变量,设置连线的条件,并按照连线的条件执行工作流,如果没有条件符合的条件,则以默认的连线离开
并行网关(ParallelGateWay)

使用场景

购物

买家付款 收货

卖家发货 收款

流程图

并行网关

部署流程

    /**
     * 部署流程
     */
    private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
    @Test
    public void deployProcess(){
        //得到RepositoryService
        RepositoryService service = processEngine.getRepositoryService();
        //部署
        InputStream isBpmn = this.getClass().getResourceAsStream("/ParallelGateWay.xml");
        InputStream isPng = this.getClass().getResourceAsStream("/ParallelGateWay.png");
        Deployment deployment = service.createDeployment().name("并行网关")//部署的名称
                .addInputStream("ParallelGateWay.bpmn", isBpmn)//设置;流程图的xml文件
                .addInputStream("ParallelGateWay.png", isPng)//设置流程图的PNG文件
                .deploy();//确定
        /**
         * act_re_deployment:流程部署表
         * act_re_model:
         * act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
         * act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
         * act_ge_property:系统内置表存放activiti的版本和自动增长的字段
         */

        System.out.println("流程部署成功:");
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名称:" + deployment.getName());
        System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
    }

启动流程

    /**
     * 启动流程
     */
    @Test
    public void startProcess(){

        /**
         * act_ru_execution:流程实例ID,里面有流动ID,流程定义ID
         * act_ru_identitylink:当前流程节点的办理人信息
         * act_ru_task:当前正在执行的流程任务表
         * act_ru_variable:执行的流程变量
         */

        //得到流程运行服务
        RuntimeService runtimeService = this.processEngine.getRuntimeService();
        //启动流程、
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ParallelGateWay");
        System.out.println("流程启动成功");
        System.out.println("流程实例ID:" + processInstance.getId());
    }

查询个人任务

    /**
     * 查询个人任务
     */
    @Test
    public void findUserTask(){
        //任务办理人
        String assignee = "买家";
        //得到任务的Service
        TaskService taskService = this.processEngine.getTaskService();
        //创建一个查询
        List<Task> list = taskService.createTaskQuery().taskId("15005").list();
        for(Task task : list){
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务办理人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getExecutionId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("流程定义ID:" + task.getProcessDefinitionId());
            System.out.println("流程:" + task.getProcessInstanceId());
            System.out.println("任务创建时间:" + task.getCreateTime());
        }
    }

完成任务

    /**
     * 完成任务
     */
    @Test
    public void completeTask(){
        String taskId = "17503";
        //得到任务的Service
        TaskService taskService = this.processEngine.getTaskService();
        //通过流程变量控制连线的走向
        taskService.complete(taskId);
        System.out.println("任务完成");
    }

总结:

  • 一个流程中流程实例只有1个,执行对象有多个

  • 并行网关的功能是基于进入和外出的顺序流的

  • 分支(fork)

    并行后的所有外出顺序流,为每个顺序流都创建一个并发分支

    汇聚(join)

    所有到达并行网关,在此等待的进入分支,直到所有进入顺序流的分支都到达以后,流程就会通过汇聚网关

  • 并行网关的进入和外出都是使用相同节点标识

  • 如果同一个并行网关有多个进入和多个外出顺序流,她就同时具有分支和汇聚功能。这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支

  • 并行网关不会解析条件,即使顺序流中定义了条件,也会被忽略。

  • 并行网关不需要是平衡的(比如,对应并行网关的进入和外出节点数目不一定相等)。

接收活动(receiveTask)

接收活动是一个简单任务,他会等待对应消息的到达。当前,官方只实现了这个任务的java语义。当流程到达接收任务,流程状态会保存到数据库中。

在任务创建后,意味着流程会进入等待状态,直到引擎接收了一个特定的消息,这会触发流程穿过接收任务继续执行。

流程图

接受活动

部署流程

/**
     * 部署流程
     */
    private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
    @Test
    public void deployProcess(){
        //得到RepositoryService
        RepositoryService service = processEngine.getRepositoryService();
        //部署
        InputStream isBpmn = this.getClass().getResourceAsStream("/ReceiveTask.xml");
        InputStream isPng = this.getClass().getResourceAsStream("/ReceiveTask.png");
        Deployment deployment = service.createDeployment().name("接收活动")//部署的名称
                .addInputStream("ReceiveTask.bpmn", isBpmn)//设置;流程图的xml文件
                .addInputStream("ReceiveTask.png", isPng)//设置流程图的PNG文件
                .deploy();//确定
        /**
         * act_re_deployment:流程部署表
         * act_re_model:
         * act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
         * act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
         * act_ge_property:系统内置表存放activiti的版本和自动增长的字段
         */

        System.out.println("流程部署成功:");
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名称:" + deployment.getName());
        System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
    }

启动流程

/**
     * 启动流程
     */
    @Test
    public void startProcess(){
        RuntimeService runtimeService = this.processEngine.getRuntimeService();
        //根据了;流程定义的KEY去启用流程
        String processDefinitionKey = "ReceiveTask";
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
        System.out.println("启动成功");
        //查询当前流程实例
        String id = processInstance.getId();
        //调用某个方法去查询数据库里面的汇总信息
        Double money = 10000.0;
        Execution execution = processEngine.getRuntimeService()
                .createExecutionQuery()//创建执行对象查询
                .processInstanceId(id)//创建流程实例ID查询
                .activityId("ReceiveTask1")//当前活动的id
                .singleResult();
        System.out.println(execution.getActivityId());
        runtimeService.setVariable(execution.getId(),"money",money);
        //把流程向下走一步
        runtimeService.signalEventReceived(execution.getId());
        //接收到这个任务
        /**
         * 查询执行对象ID
         */
        Execution execution1 = processEngine.getRuntimeService()
                .createExecutionQuery()
                .processInstanceId(id)
                .activityId("ReceiveTask2")
                .singleResult();
        //取出流程变量
        Object money1 = runtimeService.getVariable(execution1.getId(), "money");
        //调用短信或其他去向总经理发送信息
        System.out.println("发送信息:" + money1);
        //如果发送成功,再把流程向下走一步
        runtimeService.signalEventReceived(execution1.getId());


    }

说明:

当前任务(一般指机器自动完成,但需要耗费一定时间的工作)完成后,向后推移流程,可以调用RuntimeService向下执行,传递接收执行对象的id

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值