springboot + activiti6常用流程实战(顺序流程,排他网关)

本文深入讲解了工作流引擎中的并行网关与排他网关的使用,通过具体实例演示了如何利用Activiti进行流程设计与实现,包括流程启动、任务分配、审核操作及流程进度查询。

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

一.基本流程实现

流程测试我这用的是swagger,也可以用postman进行流程的运行,

       (1)先来了解什么是并行网关  图标为+

  并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进入和外出顺序流的:

  fork 分支:

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

  join 汇聚:

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

  注意:

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

      (2)什么是排他网关  图标为 -

           排他网关是用来控制流程的流向.

  并行与其他网关的主要区别:

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

流程图对应一个流程id和多个任务.每个任务对应每个人来操作.

1.普通流程,先用idea插件画BPMN流程图.这个插件画相对eclipse插件,或者activiti-app相对恶心点,不好画.如果不习惯这个插件,也可以用其他软件画好,复制过来.

2.发起流程,此流程很简单,先是主管审核,主管审完然后人事审核,流程结束,接下来开始操作

上一节config初始化配置拿到的流程相关接口注入.

   启动流程

   /**
     * 启动流程
     * @param perid
     * @param tempName
     * @param map
     * @return
     */
    @Override
    public ProcessInstance getTask(String perid, String tempName, Map<String, Object> map){
        identityService.setAuthenticatedUserId(perid);
        // 开始流程  map内容set对应的审核用户
        ProcessInstance pi = runtimeService.startProcessInstanceByKey(tempName, map);
        // 查询当前任务
        return pi;
    }

map里面对应的key可以set用户,也可以在流程图写死,一般是根据业务来进行set对应的用户(assignee属性配置)

perid 发起流程的用户

tempName 此流程的名称

3.流程启动然后到主管,用主管查询待审核的流程

    @Override
    public List<ActivitiTask> myApproval(String userName) {
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(userName)
                .orderByTaskCreateTime().desc().list();
        // 多此一举 taskList中包含了以下内容(用户的任务中包含了所在用户组的任务)
        //        Group group = identityService.createGroupQuery().groupMember(userName).singleResult();
        //        List<Task> list = taskService.createTaskQuery().taskCandidateGroup(group.getId()).list();
        //        taskList.addAll(list);
        List<ActivitiTask> activitiTaskList = new ArrayList<>();
        for (Task task : taskList) {
            ActivitiTask activitiTask = new ActivitiTask();
            activitiTask.setId(task.getId());
            activitiTask.setName(task.getName());
            activitiTask.setCreateTime(task.getCreateTime());
            String instanceId = task.getProcessInstanceId();
            ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
            Activiti activiti = getActiviti(instance);
            activitiTask.setActiviti(activiti);
            activitiTask.setProcessInstanceId(instanceId);
            activitiTaskList.add(activitiTask);
        }
        return activitiTaskList;

4,查询到待审核的任务,根据任务id和当前用户进行审核

  审核操作(审核操作可能会牵扯到是否同意,原因等字段,可以自定义进行传参)

    @Override
    public Boolean passApproval(String userName, ActivitiTask activitiTask) {
        String taskId = activitiTask.getId();
        Map<String, Object> vars = new HashMap<>();
        vars.put("result", activitiTask.getActiviti().getResult());
        vars.put("auditor", activitiTask.getActiviti().getAuditor());
        vars.put("auditTime", new Date());
        vars.put("ifPass", activitiTask.getActiviti().getIfPass());
        //taskService.claim(taskId, userName);
        taskService.setAssignee(taskId, userName);
        taskService.complete(taskId, vars);
        return true;
    }

5,审核成功之后进入人事审核,人事审核同样上述操作,审核完成,流程结束.

6.想要查看当前流程进度,查看流程图(根据流程的id获取流程图)

    /**
     * 生成流程图片
     *
     * @param processDefinitionId
     * @param outputStream
     * @return
     */
    @Override
    public void tracePhoto(String processDefinitionId, OutputStream outputStream) {
        ActUtils.getFlowImgByInstanceId(processDefinitionId, outputStream);
    }

以上基本流程代码已经可以实现流程的步骤,

二 .排他网关的流程实现

排他网关在业务流程中可能有两种或者多种选择,选择不同结果会进入的下一步流程就会不同,所以在他的后面用表达式进行区分,在实现审核的时候根据你审核的参数他会进入不同的审核状态

 用户申报流程,申报成功结转到审核,审核有两种情况,在condition属性下配置表达式,同意流程结束,不同意,退回重新申报,接下来开始操作

1.此方法操作跟上面接口一直,在审核的时候,你只需要给参数ifPass进行写入数据,同意为1,不同意为0,,如果没有满足的值会抛出异常,流程审核会根据你的条件退回去还是结束.

后面还有对应的多人顺序或者并列审核,持续学习,持续更新.

<think>好的,用户现在想在SpringBoot中集成Activiti6来实现动态流程管理。首先,我需要回忆一下之前提供的引用内容,特别是引用3,因为里面提到了SpringBoot整合Activiti6的具体步骤,包括Maven依赖、配置和数据库设置。用户提到的是动态流程管理,这可能涉及到流程的动态部署和调整,而不仅仅是静态的定义和部署。 首先,我需要确定集成的基本步骤是否正确。引用3中的步骤包括添加依赖、配置YAML文件、数据库连接设置以及排除Security依赖。这些都是基础,必须确保用户正确配置这些部分才能进行后续的动态管理。 动态流程管理可能意味着用户希望在不重启应用的情况下修改流程,或者根据运行时条件生成流程。这可能需要使用Activiti的API来动态部署流程定义,或者修改已有的流程。例如,使用RepositoryService来部署新的流程定义,或者DynamicBpmnService来修改流程参数。 然后,我需要考虑用户可能的实际需求。动态流程可能涉及流程版本控制,用户可能需要同时运行同一流程的不同版本。Activiti默认支持流程定义的版本管理,每次部署相同的流程定义会生成新版本,这一点需要明确说明。 另外,动态表单或任务分配也可能是用户关心的部分。例如,根据不同的用户或角色动态分配任务,或者在流程执行时确定下一个节点。这可能需要结合Activiti的TaskService和RuntimeService,在代码中动态设置变量或候选人。 还需要注意数据库的配置问题,引用3中提到需要在数据库连接URL中添加nullCatalogMeansCurrent=true,否则无法自动建表。这一点非常重要,否则集成会失败。同时,流程定义文件的存放位置和检查配置也需要正确设置,避免应用启动时找不到流程文件。 另外,用户可能遇到常见问题,比如依赖冲突,特别是Spring Security的依赖,因为Activiti可能会引入自己的Security组件,需要排除以避免冲突。引用3中也提到了排除Security依赖的步骤,这点需要强调。 最后,动态流程的实现可能需要编写自定义的监听器或拦截器,以便在流程执行的不同阶段注入业务逻辑。例如,使用ExecutionListener来在流程节点进入或离开时触发特定操作。 总结一下,回答的结构应该是先介绍集成步骤,然后详细说明如何通过API实现动态管理,包括流程部署、修改和版本控制,接着可能涉及动态任务分配和表单处理,最后提到常见问题及解决方法。同时,需要确保所有代码示例和配置符合用户的环境,并引用正确的资料部分,比如引用3中的配置示例。</think>以下是在SpringBoot中集成Activiti6实现动态流程管理的详细实现方案: ### 一、基础集成步骤 1. **添加Maven依赖** ```xml <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>6.0.0</version> </dependency> ``` *需排除SpringSecurity冲突*[^3] 2. **核心配置** ```yaml spring: activiti: database-schema-update: true #自动更新数据库表结构 process-definition-location-prefix: "classpath:/processes/" history-level: full #完整历史记录 datasource: url: jdbc:mysql://localhost:3306/activiti6?nullCatalogMeansCurrent=true ``` ### 二、动态流程管理实现 #### 1. 动态部署流程 通过`RepositoryService`实现运行时部署: ```java @Autowired private RepositoryService repositoryService; public void dynamicDeploy(InputStream bpmnStream) { Deployment deployment = repositoryService.createDeployment() .addInputStream("dynamic_process.bpmn20.xml", bpmnStream) .name("动态流程") .deploy(); } ``` *支持多种部署源:Classpath/File/URL/InputStream*[^3] #### 2. 流程版本控制 ```java List<ProcessDefinition> definitions = repositoryService .createProcessDefinitionQuery() .processDefinitionKey("leaveProcess") .list(); // 返回按版本倒序排列的流程定义 ``` #### 3. 动态任务分配 ```java taskService.setVariable(taskId, "assignee", "user_"+randomUser); // 通过监听器实现 @EventListener public void onTaskEvent(ActivitiEvent event) { if(event.getType() == ActivitiEventType.TASK_CREATED) { TaskService taskService = event.getEngineServices().getTaskService(); taskService.setAssignee(event.getExecutionId(), resolveAssignee()); } } ``` ### 三、动态表单集成 1. **绑定动态表单** ```xml <userTask id="approveTask" activiti:formKey="dynamic_form_${formVersion}"> </userTask> ``` 2. **运行时表单获取** ```java FormService formService = processEngine.getFormService(); String formKey = formService.getTaskFormData(taskId).getFormKey(); ``` ### 四、关键问题解决方案 1. **流程定义热更新** ```java repositoryService.suspendProcessDefinitionById(processDefinitionId); repositoryService.activateProcessDefinitionById(newDefinitionId); ``` 2. **多租户支持** ```java repositoryService.createDeployment() .tenantId("tenant_001") .addClasspathResource("processes/vacationRequest.bpmn20.xml") .deploy(); ``` ### 五、监控与调试 ```java // 流程实例状态查询 RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance instance = runtimeService .createProcessInstanceQuery() .processInstanceId(instanceId) .singleResult(); // 历史记录跟踪 HistoryService historyService = processEngine.getHistoryService(); List<HistoricActivityInstance> activities = historyService .createHistoricActivityInstanceQuery() .processInstanceId(instanceId) .list(); ``` **注意事项**: 1. 数据库配置必须包含`nullCatalogMeansCurrent=true`参数[^3] 2. 建议使用`@ActivitiComponent`注解实现服务类自动注入 3. 生产环境应设置`check-process-definitions: false`避免启动时校验
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值