【flowable】九、flowable候选人和候选人组

本文探讨了如何在Flowable流程设计中引入候选人和候选人组的概念,以增强任务的可分配性和灵活性。通过实例展示如何设置、部署和操作带有候选人任务以及使用候选人组的流程实例,包括任务查询、拾取、归还和交接,以及用户和组的管理。

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

flowable候选人和候选人组


之前在流程定义中的任务节点设置的负责人assignee都是固定的负责人,在流程定义设计时将参与者与文件固定设置了,如需变更任务负责人需要修改流程定义,系统可扩展性差。

针对这种情况可以给任务设置多个候选人或者候选人组,可以从候选人中选择参与者来完成任务。

这里讨论的是组任务,不同于流程变量来控制任务负责人。

1 候选人
1.1 设计流程

设计一个简单的新流程。

首先是“请假申请”,在分配用户项设置两个候选用户。

在这里插入图片描述

在这里插入图片描述

“经理审核”就设置一个${assignee0}流程变量即可。

1.2 部署流程和启动流程实例
/**
     * 部署流程
     */
    @Test
    public void deployment() {
        //获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RepositoryService对象,部署流程定义
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //执行部署
        repositoryService.createDeployment()
                .addClasspathResource("flowable-4.bpmn20.xml")
                .deploy();
    }

    /**
     * 启动流程
     */
    @Test
    public void startProcess() {
        //获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通过RuntimeService启动流程
        //通过流程定义ID启动流程实例
        //流程定义的ID在流程部署成功后,act_re_procdef表生成的数据主键ID就是流程定义ID
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //设置候选人流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("candidate0", "员工1");
        variables.put("candidate1", "员工2");

        ProcessInstance processInstance = runtimeService.startProcessInstanceById("flowable-4:1:10004", variables);
        // 输出相关的流程实例信息
        System.out.println("流程定义的ID:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例的ID:" + processInstance.getId());
    }

流程启动后,act_ru_variable表可以看到候选人流程变量

在这里插入图片描述

act_ru_task表的ASSIGNEE_字段是null

在这里插入图片描述

说明当前任务并没有分配给任何人,无人受理

1.3 任务查询

可以通过候选人进行查询任务

/**
     * 候选人任务查询
     */
    @Test
    public void queryTaskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取TaskService
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery().processInstanceId("12501")
                //设置taskCandidateUser候选人条件来查询任务,这里的参数值就是候选人流程变量绑定的值
                //员工1和员工2都是可以查询到数据的
                .taskCandidateUser("员工1")
                .list();
        for (Task task : taskList) {
            System.out.println("task.getId() = " + task.getId());
            System.out.println("task.getName() = " + task.getName());
        }
    }
1.4 任务拾取

根据候选人查询到任务后就可以拾取该任务。注意:当一个任务被拾取后,其他用户是无法拾取该任务的。

任务拾取成功后,就会变成个人任务

/**
     * 候选人拾取任务
     */
    @Test
    public void claimTaskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                //设置taskCandidateUser候选人条件来查询任务,这里的参数值就是候选人流程变量绑定的值
                //员工1和员工2都是可以查询到数据的
                .taskCandidateUser("员工1")
                .singleResult();


        if (task != null) {
            /**
             * 拾取任务
             * 即使该用户不是任务的候选人也可以拾取任务,建议拾取时做校验,根据候选人查询
             * 任务拾取成功后,就会变成个人任务,之后的操作就和之前一样了,complete即可
             */
            taskService.claim(task.getId(), "员工1");
        }
    }

在这里插入图片描述

说明:即使不是任务的候选人也可以进行拾取任务,所以需要根据任务候选人去查询任务再去进行拾取

1.5 任务归还

如果任务拾取之后不想操作或者误拾取任务也可以进行归还任务。

/**
     * 任务归还
     */
    @Test
    public void unClaimTaskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                //员工1拾取的任务,需要通过员工1查询
                .taskAssignee("员工1")
                .singleResult();

        if (task != null) {
            taskService.unclaim(task.getId());
        }
    }

任务成功归还后,ASSIGNEE_就会为null,需要由任务候选人重新拾取

在这里插入图片描述

1.6 任务交接

如果任务拾取后,不想操作也不想归还,可以交接给他人进行处理。

/**
     * 任务交接
     */
    @Test
    public void taskCandidate() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                //员工1拾取的任务,需要通过员工1查询
                .taskAssignee("员工1")
                .singleResult();

        if (task != null) {
            /**
             * 任务交接,就是更新任务的分配人字段
             * 由于可分配给任意的人员,所以建议实际开发中做判断处理,只将任务分配给候选人
             */
            taskService.setAssignee(task.getId(), "员工3");
        }
    }
1.7 任务完成

就是之前正常处理流程,调用complete方法

/**
     * 任务完成
     */
    @Test
    public void taskComplete() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取TaskService
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("12501")
                .taskAssignee("员工3")
                .singleResult();

        if (task != null) {
            //流程设计的时候,经理审批有个`assignee0`流程变量,所以这里设置下
            Map<String, Object> variables = new HashMap<>();
            variables.put("assignee0", "经理");
            taskService.complete(task.getId(), variables);
        }
    }
2 候选人组

当候选人很多的情况下,我们可以分组来处理。先创建组,然后把用户分配到这个组中。

2.1 管理用户和组
2.1.1 用户管理

通过act_id_user表维护用户

/**
     * 维护用户
     */
    @Test
    public void createUser() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 通过 IdentityService 完成相关的用户和组的管理
        IdentityService identityService = processEngine.getIdentityService();

        User user = null;
        for (int i = 1; i <= 3; i++) {
            user = identityService.newUser("员工" + i);
            user.setFirstName(i+"");
            user.setEmail(i+"@qq.com");
            identityService.saveUser(user);
        }
    }
2.1.2 用户组管理

通过act_id_group表维护

/**
     * 维护用户组
     */
    @Test
    public void createGroup() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 通过 IdentityService 完成相关的用户和组的管理
        IdentityService identityService = processEngine.getIdentityService();

        Group group = identityService.newGroup("group1");
        group.setName("研发部");
        group.setType("1");
        identityService.saveGroup(group);

    }
2.1.3 用户和用户组关联

通过act_id_membership表维护

/**
     * 用户和用户组关联
     */
    @Test
    public void userGroup() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        IdentityService identityService = processEngine.getIdentityService();

        // 根据组的编号找到对应的Group对象
        Group group = identityService.createGroupQuery().groupId("group1").singleResult();
        //找到用户
        List<User> users = identityService.createUserQuery().list();
        for (User user : users) {
            //用户分配给用户组
            identityService.createMembership(user.getId(), group.getId());
        }

    }
2.2 候选人组应用

用户和用户组的创建及关联搞清楚后,就可以使用候选人组实现流程任务分配了

2.2.1 设计流程

设计一个新的流程。

在这里插入图片描述

在这里插入图片描述

2.2.2 部署流程和启动流程实例
/**
     * 部署流程
     */
    @Test
    public void deployment() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();

        repositoryService.createDeployment().addClasspathResource("flowable-5.bpmn20.xml").name("候选人组流程").deploy();
    }

    /**
     * 启动流程
     */
    @Test
    public void startProcess() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //查询到用户组
        IdentityService identityService = processEngine.getIdentityService();
        Group group = identityService.createGroupQuery().groupId("group1").singleResult();

        //然后给流程设计里面的${group1}流程变量赋值
        Map<String, Object> variables = new HashMap<>();
        variables.put("group1", group.getId());

        runtimeService.startProcessInstanceById("flowable-5:1:32504", variables);
    }

act_ru_identitylink表中可以看到流程任务绑定的候选人组

在这里插入图片描述

2.2.3 任务的拾取和完成
/**
     * 查询候选人组任务
     */
    @Test
    public void queryTaskCandidateGroup() {
        //获取ProcessEngine引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //根据用户获取候选组
        IdentityService identityService = processEngine.getIdentityService();
        Group group = identityService.createGroupQuery().groupMember("员工1").singleResult();

        //获取组任务
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery()
                .processInstanceId("35001")
                .taskCandidateGroup(group.getId())
                .list();

        for (Task task : taskList) {
            System.out.println("task.getId() = " + task.getId());
            System.out.println("task.getName() = " + task.getName());
        }
    }
/**
     * 拾取组任务
     * 就是通过候选组绑定查询出来的任务,然后拾取,和普通的流程任务操作一样
     * 正常业务开发下,该组下的任务只能由该组人员拾取
     * 拾取之后,不想操作的话也可以退还或者交接给他人
     */
    @Test
    public void claimTaskCandidate() {
//获取ProcessEngine引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //根据用户获取候选组
        IdentityService identityService = processEngine.getIdentityService();
        Group group = identityService.createGroupQuery().groupMember("员工1").singleResult();

        //获取组任务
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery()
                .processInstanceId("35001")
                .taskCandidateGroup(group.getId())
                .list();

        for (Task task : taskList) {
            System.out.println("task.getId() = " + task.getId());
            System.out.println("task.getName() = " + task.getName());
            //拾取
            taskService.claim(task.getId(), "员工1");
            System.out.println("任务:"+task.getName()+"拾取成功");
        }
    }
/**
     * 完成组任务
     * 就是完成正常的一个流程任务
     */
    @Test
    public void completeTask() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();

        Task task = taskService.createTaskQuery().processInstanceId("35001").taskAssignee("员工1").singleResult();
        Assert.assertNotNull(task);
        //流程设计的时候有个assignee0流程变量,这里需要设置下
        Map<String, Object> variables = new HashMap<>();
        variables.put("assignee0", "经理");
        taskService.complete(task.getId(), variables);
    }

启动流程实例之后,查询当前任务执行表:

select * from act_ru_task;

记录了当前执行的任务,由于该任务是组任务,assignee_字段值是null,让拾取任务之后该字段才会有拾取用户的信息。

查询任务参与者:

select * from act_ru_identitylink

记录了参与任务用户或组,当前任务如果设置了候选人,就会向该表插入候选人记录,有几个候选人就插入几条记录,与act_ru_identitylink对应的还有一张历史表act_hi_identitylink,向act_ru_identitylink插入记录的同时也会向act_hi_identitylink插入记录。

<think>好的,我现在要帮用户解决关于招聘Flowable开发者的问题。首先,我需要明确用户的需求,他们想找了解Flowable工作流引擎的开发人员或专家。接下来,我得整理Flowable相关的技能要求工作经验要点。 首先,我应该回顾用户提供的引用资料。引用5提到Flowable的设计理念是轻量、灵活,支持BPMN兼容性模型驱动开发。这说明候选人需要熟悉BPMN 2.0标准,可能还需要图形化流程设计工具的经验。另外,引用34讨论了工作流的动态调整学习曲线,所以候选人可能需要有解决复杂业务逻辑优化工作流的经验,同时具备快速学习的能力。 接下来,技能方面,用户需要技术能力,比如Flowable的核心机制,BPMN,与Spring的集成,以及REST API的使用。数据库知识也很重要,因为Flowable涉及流程状态管理。此外,问题解决能力项目经验也是关键,比如处理高并发或流程优化。 工作经验部分,用户可能需要至少2年以上相关经验,参与过流程设计、集成优化的项目。团队协作沟通能力也不能忽视,毕竟开发通常需要跨团队合作。 然后,招聘渠道方面,技术社区、招聘平台内推都是有效的方式。面试环节需要设计来评估技术能力实际经验,比如案例分析或编码测试。 最后,用户可能需要相关的问题,比如如何评估Flowable技能,常见面试题,或者培训资源。这些问题能帮助他们更全面地招聘培养人才。 需要确保回答结构清晰,分点列出技能、经验、渠道面试建议,并附上相关问题。同时,引用正确的资料,比如引用5提到Flowable的BPMN兼容性,引用4提到学习曲线,引用3关于响应式工作流的优势,这些都要自然地融入回答中,确保信息准确可靠。</think>### Flowable开发者招聘技能要求与工作经验分析 #### 一、核心技能要求 1. **Flowable框架基础** - 熟悉Flowable工作流引擎的核心机制,包括流程定义、任务分配、流程实例管理历史数据追踪[^5]。 - 掌握BPMN 2.0标准,能够使用Flowable Modeler等工具进行可视化流程设计[^5]。 2. **技术栈扩展** - 熟悉Flowable与Spring/Spring Boot的集成,了解其REST API开发模式。 - 具备数据库优化能力(如MySQL、PostgreSQL),熟悉Flowable的数据库表结构设计[^5]。 3. **问题解决能力** - 能处理复杂业务逻辑的流程建模,例如条件分支、异步任务事件驱动机制[^3]。 - 有性能优化经验,如高并发场景下的流程实例调度或历史数据清理策略[^4]。 #### 二、工作经验要求 1. **项目经验** - 至少2年以上工作流开发经验,主导或参与过3个以上Flowable集成项目[^5]。 - 有跨系统集成案例,例如与ERP、OA系统的身份认证或数据同步[^2]。 2. **协作与学习能力** - 能够快速理解业务需求并转化为流程模型,适应敏捷开发模式[^4]。 - 熟悉DevOps工具链(如Jenkins、Docker)者优先。 #### 三、招聘渠道建议 1. **技术社区定向挖掘** - 在GitHub、Gitee等平台搜索Flowable相关开源项目贡献者。 - 关注BPM技术论坛(如Activiti/Flowable社区),发布招聘帖。 2. **招聘平台关键词** - 使用“Flowable开发”“BPM工程师”“工作流引擎优化”等标签筛选简历。 #### 四、面试环节设计 - **技术评估**:要求候选人解析一个BPMN流程图(如请假审批流程),并手写部分Flowable配置代码。 - **场景模拟**:给出高并发任务积压的案例,考察调优思路(如异步执行器配置或分库分表方案)[^5]。 ```java // 示例:Flowable任务查询API使用 List<Task> tasks = taskService.createTaskQuery() .processDefinitionKey("leaveApproval") .taskAssignee("kermit") .list(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值