首页 > 其他分享 >工作流之Activiti7 和BPMN讲解

工作流之Activiti7 和BPMN讲解

时间:2024-09-02 23:36:43浏览次数:8  
标签:BPMN 流之 System public 任务 Activiti7 println 流程 out

目录

1 Activiti

1.1 简介

Activiti 是一个开源的工作流和业务流程管理 (BPM) 平台,旨在帮助开发者和企业自动化业务流程。它提供了一整套工具,用于定义、执行、监控和优化业务流程。Activiti 支持 BPMN 2.0 标准,具有强大的扩展能力和易用性,适用于各种规模的组织和复杂的业务需求。
官方网站:https://www.activiti.org
https://mp.weixin.qq.com/s/Xa3yIp1FRYpQF87lmf91OA

1.2 BPMN

1.2.1 简介

BPM(Business Process Management) 即业务流程管理,是一种规范化的构造端到端的业务流程,以持续提高组织业务效率

BPMN(Business Process Model AndNotation) 即业务流程模型和符号,是一套标准的业务流程建模符号,使用 BPMN 提供的符号可以创建业务流程。Activit 就是使用 BPMN 进行流程建模、流程执行管理的
BPMN2.0 是业务流程建模符号 2.0 的缩写,它由 Business Process Management Initiative 这个非营利协会创建并不断发展。BPMN2.0 是使用一些符号来明确业务流程设计流程图的一套符号规范,能增进业务建模时的沟通效率。

1.2.2 符号

BPMN2.0 的基本符号主要包含

  • 事件 Event
    开始:表示一个流程的开始
    中间:发生的开始和结束事件之间,影响处理的流程
    结束:表示该过程结束
    在这里插入图片描述

  • 活动 Activities
    活动是工作或任务的一个通用术语。一个活动可以是一个任务,还可以是一个当前流程的子处理流程;其次,还可以为活动指定不同的类型。常见活动如下:
    在这里插入图片描述

  • 网关 GateWay
    用于表示流程的分支与合并,有几种常用网关需要了解:
    在这里插入图片描述
    排他网关:只有一条路径会被选择,基于条件选择单一路径
    并行网关:无条件并行执行所有路径
    包容网关:可以同时执行多条线路,也可以在网关上设置条件,基于条件可以选择多个路径同时执行
    事件网关:基于外部事件的发生来决定路径选择,即专门为中间捕获事件设置的,允许设置多个输出流指向多个不同的中间捕获事件。当流程执行到事件网关后,流程处于等待状态,需要等待抛出事件才能将等待状态转换为活动状态

  • 流向 Flow
    流是连接两个流程节点的连线,常见的流向包含以下几种:
    顺序流:用一个带实心箭头的实心线表示,用于指定活动执行的顺序
    信息流:用一条带箭头的虚线表示,用于描述两个独立的业务参与者(业务实体/业务角色)之间发送和接受的消息流动
    关联:用一根带有线箭头的点线表示,用于将相关的数据、文本和其他人工信息与流对象联系起来。用于展示活动的输入和输出
    在这里插入图片描述

  • 边界事件(Boundary Events
    边界事件是一种特殊的事件,它附加在流程元素(如任务、子流程等)上,用于捕捉特定事件并对其进行处理。边界事件通常用于中断或处理任务的异常情况,或者处理流程中某些特定的事件场景。

    • 中断任务: 当绑定在某个任务上的边界事件被触发时,任务可以被中断,流程将根据边界事件的定义跳转到其他节点或执行特定的操作。这通常用于处理异常情况,如错误、超时等。
    • 捕获事件: 边界事件可以用来捕捉在任务执行过程中发生的特定事件,例如错误事件(Error Event)、定时事件(Timer Event)、消息事件(Message Event)等。当这些事件发生时,流程会从当前任务转移到处理该事件的流程路径。
    • 处理子流程: 在嵌套子流程中,边界事件可以用于在子流程内某个特定事件发生时触发相应的处理逻辑。

1.3 准备工作

1.3.1 安装插件

1.3.1.1 插件

IDEA版本小于等于2019,可使用Activiti插件actiBPM,如果获取不到插件市场获取:https://plugins.jetbrains.com/plugin/7429-actibpm
否则使用Activiti BPMN visualizer
在这里插入图片描述
假如要画一个请假的 activiti 流程图,使用 Idea 安装 actiBPM 插件,创建该流程图,文件命名apply.mpmn,实现请假流程的二级审批能力,右键点击view bpmn diagram 才会有图示出来
在这里插入图片描述

1.3.1.2 本地网页

如果觉得插件画图麻烦,可以用 Activiti ModelerActiviti Modeler 是 Activiti 官方提供的一款在线流程设计的前端插件,开发人员可以方便在线进行流程设计,保存流程模型,部署至流程定义等等

下载activiti-explorer,官网下载:Get started | Activiti
解压activiti-5.22.0.zip,在activiti-5.22.0\wars目录下获取activiti-explorer.war
启动路径:双击startup.bat
在这里插入图片描述

访问activiti-explorer:http://localhost:8080/activiti-explorer
默认登录账号:kermit kermit

1.3.2 pom依赖

<!--引入activiti的springboot启动器 -->
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.1.0.M6</version>
    <exclusions>
        <exclusion>
            <artifactId>mybatis</artifactId>
            <groupId>org.mybatis</groupId>
        </exclusion>
    </exclusions>

	<!-- 不加如下依赖报错:'org.springframework.security.core.userdetails.UserDetailsService' that could not be found. 
	-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
<!-- 不加可能报错:Consider defining a bean of type 'javax.sql.DataSource' in your configuration -->
	<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <!-- 或者使用druid-spring-boot-starter -->
    </dependency>
</dependency>

说明:Activiti7SpringBoot整合后,默认集成了SpringSecurity安全框架,当前项目已经集成过了SpringSecurity,后续案例设置审批人时都必须是系统用户,Activiti框架会检查用户是否存在,否则会出现异常

1.3.3 添加配置

数据源项目已经添加,只需要如下配置即可

spring:
  datasource:
    url: jdbc:mysql://localhost:3316/activiti?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: xxxx
    password: xxxx
    driver-class-name: com.mysql.cj.jdbc.Driver
  activiti:
    #    false:默认,数据库表不变,但是如果版本不对或者缺失表会抛出异常(生产使用)
    #    true:表不存在,自动创建(开发使用)
    #    create_drop: 启动时创建,关闭时删除表(测试使用)
    #    drop_create: 启动时删除表,在创建表 (不需要手动关闭引擎)
    database-schema-update: true
    #监测历史表是否存在,activities7默认不开启历史表
    db-history-used: true
    #none:不保存任何历史数据,流程中这是最高效的
    #activity:只保存流程实例和流程行为
    #audit:除了activity,还保存全部的流程任务以及其属性,audit为history默认值
    #full:除了audit、还保存其他全部流程相关的细节数据,包括一些流程参数
    history-level: full
    #校验流程文件,默认校验resources下的process 文件夹的流程文件
    check-process-definitions: false
    # 定义.bpmn文件的位置
    process-definition-location-prefix: classpath:/process/

1.3.4 表介绍

启动项目,即可生成项目数据库表
在这里插入图片描述
Activiti 的运行支持必须要有这 25 张表的支持,主要是在业务流程运行过程中,记录参与流程的用户主体,用户组信息,以及流程的定义,流程执行时的信息,和流程的历史信息等等

表的命名规则和作用:

  • Activiti 的表都以 act_ 开头,紧接着是表示表的用途的两个字母标识,也和 Activiti 所提供的服务的 API 对应:
    • ACT_RE:RE 表示 repository,这个前缀的表包含了流程定义和流程静态资源 (图片、规则、等等)
    • ACT_RU:RU 表示 runtime,这些表运行时,会包含流程实例、任务、变量、异步任务等流程业务进行中的数据。Activiti 只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录。这样表就可以一直保持很小的体积,并且速度很快
    • ACT_HI:HI 表示 history,这些表包含一些历史数据,比如历史流程实例、变量、任务等等
    • ACT_GE:GE 表示 general,通用数据

Activiti 数据表介绍

表分类 表名 解释
一般数据
[ACT_GE_BYTEARRAY] 通用的流程定义和流程资源
[ACT_GE_PROPERTY] 系统相关属性
流程历史记录
[ACT_HI_ACTINST] 历史的流程实例
[ACT_HI_ATTACHMENT] 历史的流程附件
[ACT_HI_COMMENT] 历史的说明性信息
[ACT_HI_DETAIL] 历史的流程运行中的细节信息
[ACT_HI_IDENTITYLINK] 历史的流程运行过程中用户关系
[ACT_HI_PROCINST] 历史的流程实例
[ACT_HI_TASKINST] 历史的任务实例
[ACT_HI_VARINST] 历史的流程运行中的变量信息
流程定义表
[ACT_RE_DEPLOYMENT] 部署单元信息
[ACT_RE_MODEL] 模型信息
[ACT_RE_PROCDEF] 已部署的流程定义
运行实例表
[ACT_RU_EVENT_SUBSCR] 运行时事件
[ACT_RU_EXECUTION] 运行时流程执行实例
[ACT_RU_IDENTITYLINK] 运行时用户关系信息,存储任务节点与参与者的相关信息
[ACT_RU_JOB] 运行时作业
[ACT_RU_TASK] 运行时任务
[ACT_RU_VARIABLE] 运行时变量表

1.3.5 常用Service服务介绍

各个 Service 的实现类,这些服务是 Activiti 的底层核心 API,提供了对工作流引擎内部的细粒度控制。它们是 Activiti 5 和 6 中主要使用的服务,提供了更低级别的操作接口:

  • RepositoryService
    Activiti 的资源管理类,该服务负责部署流程定义,管理流程资源。在使用 Activiti 时,一开始需要先完成流程部署,即将使用建模工具设计的业务流程图通过 RepositoryService 进行部署
  • RuntimeService
    Activiti 的流程运行管理类,用于开始一个新的流程实例,获取关于流程执行的相关信息。流程定义用于确定一个流程中的结构和各个节点间行为,而流程实例则是对应的流程定义的一个执行,可以理解为 Java 中类和对象的关系
  • TaskService
    Activiti 的任务管理类,用于处理业务运行中的各种任务,例如查询分给用户或组的任务、创建新的任务、分配任务、确定和完成一个任务
  • HistoryService
    Activiti 的历史管理类,可以查询历史信息。执行流程时,引擎会保存很多数据,比如流程实例启动时间、任务的参与者、完成任务的时间、每个流程实例的执行路径等等。这个服务主要通过查询功能来获得这些数据
  • ManagementService
    Activiti 的引擎管理类,提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于 Activiti 系统的日常维护

Activiti7后新增服务:

  • TaskRuntime:这个服务主要用于管理用户任务。通过它,可以查询任务、完成任务、分配任务、认领任务等。这些操作是围绕任务管理的高层次抽象,开发人员可以更加方便地与任务进行交互,而无需直接处理底层的 API 调用。
  • ProcessRuntime:这个服务用于管理流程实例。可以通过它启动流程、查询流程实例、暂停和恢复流程等。ProcessRuntime 提供了一个更简单的方式来处理流程的生命周期管理。

1.4 无校验操作流程

将画好的流程图部署到activiti数据库中,就是流程定义部署。通过调用activiti的api将流程定义的bpmn和png两个文件一个一个添加部署到activiti中,也可以将两个文件打成zip包进行部署。

1.4.1 部署&查看文件

流程定义部署后操作activiti的3张表如下:

  • act_re_deployment:流程定义部署表,每部署一次增加一条记录
  • act_re_procdef:流程定义表,部署每个新的流程定义都会在这张表中增加一条记录
  • act_ge_bytearray:流程资源表

1.4.1.1 单个文件部署方式


@SpringBootTest
public class ProcessTest {

    //注入RepositoryService
    @Autowired
    private RepositoryService repositoryService;

    /**
     * 单个文件部署方式
     */
    @Test
    public void deployProcess() {
        //流程部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("process/qingjia.bpmn20.xml")
                // 如果报错找不到图片在pom里面添加: <include>**/*.png</include>
               
                .addClasspathResource("process/qingjia.png")
                .name("请假申请流程")
                .deploy();
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());
    }
}

1.4.1.2 静态类部署

	@Test
    public void testDeployment(){
//        1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        3、使用RepositoryService进行部署
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("process/qingjia.bpmn") // 添加bpmn资源 
                .name("请假申请流程")
                .deploy();
//        4、输出部署信息
        System.out.println("流程部署id:" + deployment.getId());
        System.out.println("流程部署名称:" + deployment.getName());
    }

1.4.1.3 压缩包部署方式

@Autowired
private RepositoryService repositoryService;
@Test
public void deployProcessByZip() {
    // 定义zip输入流
    InputStream inputStream = this
            .getClass()
            .getClassLoader()
            .getResourceAsStream(
                    "process/qingjia.zip");
    ZipInputStream zipInputStream = new ZipInputStream(inputStream);

    // 流程部署
    Deployment deployment = repositoryService.createDeployment()
            .addZipInputStream(zipInputStream)
            .name("请假申请流程")
            .deploy();
    System.out.println("流程部署id:" + deployment.getId());
    System.out.println("流程部署名称:" + deployment.getName());
}

1.4.1.4 查看文件

@Test
public void  queryBpmnFile() throws IOException {
//得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey("qingjia")
            .singleResult();
//通过流程定义信息,得到部署ID
    String deploymentId = processDefinition.getDeploymentId();
//  通过repositoryService的方法,实现读取图片信息和bpmn信息
//        png图片的流
    InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
//        bpmn文件的流
    InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
//  构造OutputStream流
    File file_png = new File("d:/qingjia.png");
    File file_bpmn = new File("d:/qingjia.bpmn");
    FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
    FileOutputStream pngOut = new FileOutputStream(file_png);
//        7、输入流,输出流的转换
    IOUtils.copy(pngInput,pngOut);
    IOUtils.copy(bpmnInput,bpmnOut);
//        8、关闭流
    pngOut.close();
    bpmnOut.close();
    pngInput.close();
    bpmnInput.close();
}

1.4.2 启动流程实例和查询

将bpmn文件放到activiti的三张表中,好比是java中的一个类 流程实例:好比是java中的一个实例对象(一个流程定义可以对应多个流程实例),张三可以启动一个请假流程实例,李四也可以启动一个请假流程实例,他们互不影响

@Autowired
private RuntimeService runtimeService;

@Test
public void startUpProcess() {
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia");
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
    System.out.println("当前活动Id:" + processInstance.getActivityId());
}

注意:使用startProcessInstanceByKey的方式不用在部署了,springboot会自动部署bpmn文件
操作数据表:

  • act_hi_actinst 流程实例执行历史
  • act_hi_identitylink 流程的参与用户历史信息
  • act_hi_procinst 流程实例历史信息
  • act_hi_taskinst 流程任务历史信息
  • act_ru_execution 流程执行信息
  • act_ru_identitylink 流程的参与用户信息
  • act_ru_task 任务信息
/**
 * 查询流程实例
 */
@Test
public void queryProcessInstance() {
    List<ProcessInstance> list = runtimeService
            .createProcessInstanceQuery("qingjia")
            .processDefinitionKey()//
            .list();

    for (ProcessInstance processInstance : list) {
        System.out.println("----------------------------");
        System.out.println("流程实例id:"
                + processInstance.getProcessInstanceId());
        System.out.println("所属流程定义id:"
                + processInstance.getProcessDefinitionId());
        System.out.println("是否执行完成:" + processInstance.isEnded());
        System.out.println("是否暂停:" + processInstance.isSuspended());
        System.out.println("当前活动标识:" + processInstance.getActivityId());
        System.out.println("业务关键字:"+processInstance.getBusinessKey());
    }
}

查看流程实例历史

/**
 * 查看历史信息
 */
@Test
public void findHistoryInfo(){
//        获取 actinst表的查询对象
    HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//        查询 actinst表,条件:根据 InstanceId 查询,查询一个流程的所有历史信息
    instanceQuery.processInstanceId("25001");
//        查询 actinst表,条件:根据 DefinitionId 查询,查询一种流程的所有历史信息
//        instanceQuery.processDefinitionId("myLeave:1:22504");
//        增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
    instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//        查询所有内容
    List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
//        输出
    for (HistoricActivityInstance hi : activityInstanceList) {
        System.out.println(hi.getActivityId());
        System.out.println(hi.getActivityName());
        System.out.println(hi.getProcessDefinitionId());
        System.out.println(hi.getProcessInstanceId());
        System.out.println("<==========================>");
    }
}

1.4.3 查询任务和历史

每个节点都配置了Assignee,流程启动后,任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。

@Autowired
private TaskService taskService;
​
/**
 * 查询当前个人待执行的任务
 */
@Test
public void findPendingTaskList() {
    //任务负责人
    String assignee = "zhangsan";
    List<Task> list = taskService.createTaskQuery()
    		.processDefinitionKey("qingjia") //流程Key
            .taskAssignee(assignee)//只查询该任务负责人的任务
            .list();
    for (Task task : list) {
        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("任务id:" + task.getId());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName());
    }
}

@Autowired
private HistoryService historyService;
​
/**
 * 查询已处理历史任务
 */
@Test
public void findProcessedTaskList() {
    //张三已处理过的历史任务
    List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
	.processDefinitionKey("qingjia") //流程Key
	.taskAssignee("zhangsan").finished().list();
    for (HistoricTaskInstance historicTaskInstance : list) {
        System.out.println("流程实例id:" + historicTaskInstance.getProcessInstanceId());
        System.out.println("任务id:" + historicTaskInstance.getId());
        System.out.println("任务负责人:" + historicTaskInstance.getAssignee());
        System.out.println("任务名称:" + historicTaskInstance.getName());
    }
}

说明:

  • 流程实例id:一个流程只有一个,标识这个流程
  • 任务id:流程每进行到某个节点,就会给这个节点分配一个任务id

1.4.4 处理当前任务

任务负责人查询待办任务,选择任务进行处理,完成任务。

@Test
public void completTask(){
    Task task = taskService.createTaskQuery()
    		.processDefinitionKey("qingjia") //流程Key
            .taskAssignee("zhangsan")  //要查询的负责人
            .singleResult();//返回一条
​
    //完成任务,参数:任务id
    taskService.complete(task.getId());
}

完成任务后,任务自动到下一个节点

1.4.5 流程定义

/**
 * 查询流程定义
 */
@Test
public void findProcessDefinitionList(){
    List<ProcessDefinition> definitionList = repositoryService.createProcessDefinitionQuery()
    		.processDefinitionKey("qingjia")
            .orderByProcessDefinitionVersion()
            .desc()
            .list();
    //输出流程定义信息
    for (ProcessDefinition processDefinition : definitionList) {
        System.out.println("流程定义 id="+processDefinition.getId());
        System.out.println("流程定义 name="+processDefinition.getName());
        System.out.println("流程定义 key="+processDefinition.getKey());
        System.out.println("流程定义 Version="+processDefinition.getVersion());
        System.out.println("流程部署ID ="+processDefinition.getDeploymentId());
    }
}
​
/**
 * 删除流程定义
 */
public void deleteDeployment() {
    //部署id
    String deploymentId = "82e3bc6b-81da-11ed-8e03-7c57581a7819";
    //删除流程定义,如果该流程定义已有流程实例启动则删除时出错
    repositoryService.deleteDeployment(deploymentId);
    //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式
    //repositoryService.deleteDeployment(deploymentId, true);
}

1.5 新版校验操作

1.5.1 配置Security用户

@Configuration
@EnableWebSecurity
public class MyWebSecurityConfiguration {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests(authorize -> authorize.anyRequest().authenticated())
                .formLogin(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring()
                .requestMatchers()
                // Spring Security should completely ignore URLs starting with /resources/
                .antMatchers("/**");
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails admin = User.withUsername("tom")
                .password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC")
                .roles("ACTIVITI_USER", "ACTIVITI_ADMIN", "APPLICATION_MANAGER")
                .build();
        UserDetails user = User.withUsername("jerry")
                .password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC")
                .roles("ACTIVITI_USER", "GROUP_BUSINESS_MANAGER")
                .build();
        UserDetails zhangsan = User.withUsername("zhangsan")
                .password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC")
                .roles("ACTIVITI_USER")
                .build();
        UserDetails lisi = User.withUsername("lisi")
                .password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC")
                .roles("ACTIVITI_USER")
                .build();
        return new InMemoryUserDetailsManager(admin, user, zhangsan, lisi);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    public static void main(String[] args) {
        System.out.println(new BCryptPasswordEncoder().encode("123456"));
    }
}

Security工具类

@Component
public class SecurityUtil {

    @Autowired
    private UserDetailsService userDetailsService;

    public void logInAs(String username) {
        UserDetails user = userDetailsService.loadUserByUsername(username);
        if (null == user) {
            throw new IllegalStateException(String.format("用户【%s】不存在", username));
        }
        SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                return user.getAuthorities();
            }

            @Override
            public Object getCredentials() {
                return user.getPassword();
            }

            @Override
            public Object getDetails() {
                return user;
            }

            @Override
            public Object getPrincipal() {
                return user;
            }

            @Override
            public boolean isAuthenticated() {
                return true;
            }

            @Override
            public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

            }

            @Override
            public String getName() {
                return user.getUsername();
            }
        }));
        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    }
}

1.5.2 操作

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestSecurityActiviti {

    @Autowired
    private ProcessRuntime processRuntime;

    @Autowired
    private TaskRuntime taskRuntime;

    @Autowired
    private SecurityUtil securityUtil;

    @Test
    public void findProcess(){
        securityUtil.logInAs("jack");

        final ProcessDefinition processDefinition = processRuntime.processDefinition("apply");
        log.info("流程定义内容:{}",processDefinition);

        final Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
        for (ProcessDefinition definition : processDefinitionPage.getContent()) {
            log.info("2- 流程定义内容:  {}",definition);
        }
    }

    /**
     * 启动流程
     */
    @Test
    public void startProcess(){
//        设置登录用户
        securityUtil.logInAs("system");
        ProcessInstance processInstance = processRuntime.
                start(ProcessPayloadBuilder.
                        start().
                        withProcessDefinitionKey("apply").
                        build());
        log.info("流程实例的内容,{}",processInstance);
    }

    /**
     * 执行任务
     */
    @Test
    public void doTask(){
//        设置登录用户
        securityUtil.logInAs("jerry");
//        查询任务
        Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 10));
        if(taskPage != null && taskPage.getTotalItems()>0){
            for (Task task : taskPage.getContent()) {
                //        拾取任务
                taskRuntime.claim(TaskPayloadBuilder.
                        claim().
                        withTaskId(task.getId()).
                        build());
                log.info("任务内容,{}",task);
                //        完成任务
                taskRuntime.complete(TaskPayloadBuilder.
                        complete().
                        withTaskId(task.getId()).
                        build());
            }
        }
    }
}

1.5.3 报错 Process definition with the given id:xxx belongs to a different application version

报错参考:https://blog.csdn.net/u011410254/article/details/117368489
在resources目录下添加文件default-project.json内容:

{
  "createdBy": "superadminuser",
  "creationDate": "2019-08-16T15:58:46.056+0000",
  "lastModifiedBy": "qa-modeler-1",
  "lastModifiedDate": "2019-08-16T16:03:41.941+0000",
  "id": "c519a458-539f-4385-a937-2edfb4045eb9",
  "name": "projectA",
  "description": "",
  "version": "1"
}

application配置文件:


# project manifest path
project.manifest.file.path=classpath:/default-project.json

1.6 Activiti 7.1.0.M6之后

activiti-spring-boot-starter最大是支持到7.1.0.M6,在大版本就需要 如下处理
pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-dependencies</artifactId>
                <version>7.6.1</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <repositories>
        <repository>
            <id>activiti-releases</id>
            <url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases</url>
        </repository>
    </repositories>

修改 mirror 镜像

  <mirrors>
	 <mirror>
		<id>nexus-aliyun</id>
		<mirrorOf>*,!activiti-releases</mirrorOf>
		<url>https://maven.aliyun.com/repository/public</url>	
	</mirror>
  </mirrors>

标签:BPMN,流之,System,public,任务,Activiti7,println,流程,out
From: https://www.cnblogs.com/jingzh/p/18393744

相关文章

  • JAVA-IO流之字节的输入输出流
    一、IO流的分流按流的流向分为:输入流、输出流根据处理的数据类型分为:字节流、字符流在计算机中、将硬盘上的文件向内存中的流为输入流(读取)、将内存中的流输出到硬盘为输出流(写)二、java流-字节输入输出流概念:流可以理解为一个数据序列、输入流表示从一个源读取数据,输出流表......
  • [JavaEE] 工作流- Activiti7 框架详解
    目录1、Activiti介绍1.1、BPMN设计器1.2、常见流程符号1.2.1、事件event1.2.2、活动activiti1.2.3、流向flow2、入门案例2.1、需求说明2.2、初始环境2.2.1、添加依赖2.2.2、添加配置2.2.3、添加引导类2.2.4、启动项目2.2.5、表结构2.2.6、常见api2.3、绘制流......
  • 工作流之Flowable与SpringBoot结合
    目录1Flowable1.1flowable-ui部署运行1.2绘制流程图1.2.1绘制1.2.2绘图细节1.2.3bpmn文件导入1.3后台项目搭建1.3.1pom.xml1.3.2数据库表说明1.4流程引擎API与服务1.4.1主要API1.4.2示例1Flowable1.1flowable-ui部署运行flowable-6.6.0运行官方demo参考文档:ht......
  • vue2 bpmnjs流程图
    原作者gitee地址:gitclonehttps://gitee.com/cjy2353/best-vue-bpmnjs.git"bpmn-js":"^17.9.2","vue":"^2.6.11",node-v"v14.17.6"使用:`importBpmnfrom'com/Bpmn'components:{Bpmn,},`bpmn组件如下:......
  • BPMN学习
    目录BPMN学习BPMN简介BPMN的四种基本元素BPMN图的主要组件流程节点的类型和描述连接元素的作用辅助元素的定义如何阅读BPMN图利用BPMN图进行业务流程建模建模步骤概述实际案例展示和分析BPMN图与其他流程图的比较与EPC、UML等流程图的对比BPMN图的优势和应用领域BPMN图的应用典型......
  • BPMN—工作流技术的理论与实践
    一、前言19世纪70年代,流程管理思想萌芽阶段。怎样提高工作效率?泰勒:标准化个人操作流程亨利·福特:规定标准时间定额标准化、精简化、通用化、专业化。20世纪70年代,工作流技术起源于办公自动化领域的研究。由于当时计算机尚未普及,网络技术水平还很低以及理论基础匮乏,这项新技......
  • Canvas+bpmn.js 流程节点鼠标悬浮显示信息 (全网首发)
    customBpmn.jsimportinheritsfrom"inherits";importViewerfrom"bpmn-js/lib/Viewer";importZoomScrollModulefrom"diagram-js/lib/navigation/zoomscroll";importMoveCanvasModulefrom"diagram-js/lib/navigation/moveca......
  • camunda快速入门(二):设计并执行第一个BPMN流程
    二、设计并执行第一个BPMN流程在本节中,您将学习如何使用CamundaModeler创建您的第一个BPMN2.0流程,以及如何执行自动化步骤。首先打开CamundaModeler。1、创建BPMN流程通过单击File>NewFile>BPMNDiagram(CamundaPlatform)创建新的BPMN图。1.1、从一个简单......
  • activiti流程配置——vue整合bpmn.js
    acitivti提供了流程图绘制的应用,可以整合到流程项目钟。但是现在很多项目都是前后端分离,vue前端开发比较多。所以,我用vue整合了一下bpmn。具体的整合过程,网上有大把的资料可以参考;我这边就不罗列了。我主要记录一下,vue整合bpmn过程中,对于activiti流程而言有几个地方要注意:......
  • OA自动化办公: springboot集成Activiti7
    一.场景引入    我在实际开发中遇到过这样一个需求:公民登录建议征集系统向大冶市某个人大代表提建议,但建议提出后人大代表未能及时响应,此时如果建议越来越多,就会导致建议被搁置。很多建议不会被处理,公民自然也就得不到反馈,这对于汇聚民生民意和征集建议显然是不利的。......