基于Camunda实现bpmn 2.0各种类型的任务

基于Camunda实现bpmn中各种类型任务

​ Camunda Modeler -为流程设置器(建模工具),用来构建我们的流程模型。Camunda Modeler流程绘图工具,支持三种协议类型流程文件分别为:BPMN、DMN、Form。

​ Camunda Modeler下载地址:https://camunda.com/download/modeler/

​ 继 springboot集成Camunda审核流程(二):Camunda Modeler设计器设置BPMN流程 继续对流程设计器以及bpmn协议相关知识进行记录扩展。本文章主要记录 bpmn 协议中的各种类型的任务基于Camunda流程控制引擎的实现方式!

​ 在bpmn协议中常用的任务类型主要有:用户任务(user task)、服务任务(service task)、脚本任务(script task)、发送任务(send task)、接收任务(receice task) …等。

备注:其它功能的使用铺垫

一、Camunda 控制台用户功能

​ Camunda流程引擎内置了用户管理相关的操作,可以通过Camunda内置控制台创建对应的用户组、用户等操作,后续可以直接通过内置的控制台实现对流程的审核过程!

​ 配置依赖见文: springboot集成Camunda审核流程(一):Springboot集成配置

​ 可以通过Camunda 控制台 配置用户信息、用户组信息,同时给对应的用户组分配系统的操作权限等功能。在这里插入图片描述

​ 这里就不详细扩展,需要知道Camunda内置的该功能。后续在测试流程的各种任务时,就可以通过登录创建的不同用户账号对流程进行审核操作(也可以自己写审核接口来实现不同用户对节点的审核操作,但是这里Camunda已经内置了类似的审核平台,就直接使用就不用在写各种审核、驳回等接口)!从而实现对流程的测试。

​ 需要在Camunda控制台创建若干用户,后续登录对应用户,对对应的任务节点进行审核操作!

二、Camunda Modeler部署流程

​ 在Camunda-Modeler 流程设计器中,可以直接将我们设计的流程模板部署到对应的后台程序中,同时也可以通过流程设计器直接启动对应流程模板的实例,就无需手动写接口实现流程模板的部署和流程实例的启动等功能:

​ 1、camunda-Modeler流程设计器中 流程模型的部署功能:在这里插入图片描述

​ 2、camunda-Modeler流程设计器中 启动流程实例的功能在这里插入图片描述

​ 这里通过 Start process instance 操作 就可以 直接启动流程实例,但是需要注意的是,在流程设计器中启动流程实例时,无法给流程中需要的流程变量赋值,所有当流程中需要给预置的流程变量赋值时,就不能在流程设计器中进行启动流程实例。

​ 需要给流程中流程变量赋初始值时可以通过Camunda控制台启动流程实例,或者构建一个简单的流程实例启动接口。 eg:在这里插入图片描述

一、用户任务 user task

​ 需要在项目程序中人为处理干预后才能流转的任务类型

在这里插入图片描述

1.1 用户任务受理人设置

User assignment 栏目中主要设置节点对应审核人的参数。

在这里插入图片描述

​ 参数的填写可以设置为固定字符串(eg:“xx” ),表示后续该节点的受理人就由 xx 进行受理审核。也可以通过 UEL表达式 / UEL方法表达式 的方式进行填写,后续在程序中给对应的 流程变量Key 赋值即可!

  • 使用UEL表达式

    ​ 设置节点审核人的方式(eg: ${userID})。

    ​ 当流程实例运行到该节点后,会自动查询该流程实例的流程变量中 该 userID 所对应的数据,就会自动将该Key对应的value值设置为该节点的审核人。

    ​ 在代码中需要在实例运行到当前节点之前,对对应的流程变量进行赋值,这一步可以通过流程监听器来实现。或者是在流程创建初期,通过制单人信息,将对应的审核人确定好之后对对应流程变量进行赋值!

  • 使用 UEL方法表达式

    ​ 当使用 UEL方法表达式(eg: ${uelMethodListener.getAssignee(execution)})来确定流程节点审核人时。当流程实例审核到该节点后,会解析到该UEL方法表达式。

    ​ 以示例中的 UEL方法表达式为例,当执行当该节点后,流程引擎就会通过 uelMethodListener对象,调用getAssignee()方法,来获取对应的节点受理人。其中的 execution 是传入的节点相关的信息参数。在后台代码中的具体封装如下:在这里插入图片描述

1.2 流程内置表单的使用

​ Camunda-bpmn 流程设计器中,可以创建内置的任务表单,当流程执行到相关任务节点时,需要我们人工处理填写创建表单的任务信息。填写完成后,对应的表单数据会自动生成为对应流程实例的流程变量。该流程变量数据就可以用来作为后续流程中的分支条件参数等作用!

在这里插入图片描述

  • 任务表单实现效果

    ​ 设置好任务内置表单后,启动流程实例时,运行到对应节点,就会触发内置表单的填写(这里就使用了Camunda内置控制台来对任务进行审核操作。

    ​ 上文备注内容中介绍了,创建对应节点审核人的账号)在Camunda内置控制台中,登录对应的审核人通过TskList中就能查询到该用户名下对应需要审核的任务节点。在这里插入图片描述

  • 审核通过任务表单节点后续效果

    将任务表单对应审核人登录到Camunda内置控制台,对表单内容填写后,审核通过该节点的效果展示:在这里插入图片描述

1.3 多实例节点设置

​ 多实例(会签/或签)节点 是指 实现多个用户对一个 用户任务节点进行操作的方式。在这里插入图片描述

​ 在用户节点(user task) 的基础上可设置会签 /或签节点 (多实例节点)。当节点设置为多实例节点后,流程实例中会自动生成相关参数的流程变量用来记录该节点相关数据信息:

nrOfInstances:多实例节点中总共的实例数(实例总数)

nrOfActiviteInstances:当前活动的实例数量,即还没有完成的实例数量对应串行而言该值始终为1

loopCounter :循环计数器,办理人在列表中的索引

nrOfCompletedInstances:已经完成的实例数量

loop cardinality:循环基数。可选项。可以直接填整数,表示会签的人数。

Collection:集合。可选项。会签人数的集合,通常为list,和loop cardinality二选一。

Element variable:元素变量。选择Collection时必选,为collection集合每次遍历的元素。

Completion condition:完成条件。可选。比如设置一个人完成后会签结束,那么其他人的代办任务都会消失在这里插入图片描述

  • 串行/并行 多实例节点的设置

    ​ 串行 和 并行 多实例节点的区别在与,集合中的受理人在对目标节点进行审核是,是否需要按照顺序进行受理审核。

    ​ 当设置为并行(III) 时,多实例集合中的所有受理人,不需要按照相关顺序执行,可以随意顺序对多实例节点进行审核操作;当设置为串行(三) 多实例节点时,多实例集合中的审核人,就必须按照一定顺序依次一个一个的对目标节点进行审核。

  • 会签/或签 节点的设置

    ​ 会签节点指 多实例任务节点 的 多实例集合中的所有审核人都审核通过,该节点才算完成。

    ​ 或签节点指 多实例任务节点 的 多实例集合中的审核只需要一个或者多个审核通过后,该多实例任务就算完成。

    ​ 设置会签/或签节点的方式主要是通过 **多实例设置栏目(Multi-instance)**中的 **节点完成条件(Completion condition)**来体现出来,通过上文注释中的参数加上UEL表达式封装来设置:
    会签节点:nrOfCompletedInstances == nrOfInstances (完成实例数 == 实例总数)
    或签节点:nrOfCompletedInstances == 1(完成实例数 ==1)
    Camunda流程引擎会自动根据设置的多实例节点完成条件来判断,该多实例节点是否结束后跳转到下一任务节点。

  • 会签节点审核人动态设置方式

    ​ 首先在 **多实例设置栏目(Multi-instance)**中的 **多实例集合(Collection)**项中,用 UEL表达式 将多实例集合的Key值设置上(eg: ${leaders} )。

    ​ 然后在通过项目代码中,动态的为 多实例结合赋值,并传入对应流程实例中即可 完成对多实例节点的审核人动态设置!在这里插入图片描述

1.4 开始节点Initiator的设置

​ 在开始节点中我们可以为 流程发起人Initiator 中设置一个 Key 值,在后续启动流程时调用接口API 设置发起人信息,就会自动生成一个对应Key值的流程变量作为我们流程发起人。然后在第一个节点就可以直接引用该 Key值,作为流程的第一个节点审核人(制单人)。

  • 在bpmn流程的开始节点设置发起人Key值在这里插入图片描述

  • 在流程任务的第一个用户节点(通常为制单人节点),将审核人设置为对应的Key值

    后续通过调用Camunda内置APi即可自动设置流程发起人信息,并会作为流程变量存储到对应的流程数据中。在这里插入图片描述

  • 在项目中启动流程时通过调用内置Api即可完成对流程发起人变量的赋值在这里插入图片描述

二、服务任务 service task

​ 服务任务通常是调用业务系统,Camunda中 可以调用 java代码。

在这里插入图片描述

​ 服务任务 service task 常见的实现方式主要有四种: External外部任务实现、Java class 指定java类实现、Expression 表达式实现、Delegate expression 代理表达式实现。

在这里插入图片描述

​ 选中不同的实现方式,需要做出对应的处理方法,当流程实例执行到服务任务时,会根所设定的实现方式进行对应的处理。

2.1 外部实现方式 External

​ 在service task 服务任务Type选项选用 **外部实现方式 External **时,对应的 Topic中需要自定义一个主题,作为该服务任务的唯一标识。

在这里插入图片描述

  • 外部任务实现方式一
    在客户端系统中(外部系统),会创建外部任务处理的对应类,会实时监听相关任务。 具体的实现方式如下代码:
package cn.zhidasifang.flowmanagement.camundaExternalClient.shopping;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.client.ExternalTaskClient;
import org.camunda.bpm.engine.variable.Variables;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * @ClassName : SubscribeTask
 * @Description : 业务任务节点 Service-Task 【External 类型的业务任务】
 * @Author : AD
 */

@Component
@Slf4j
public class SubscribeTask {
    /**
     * 引擎端url 前缀
    */
    private final static String CAMUNDA_BASE_URL = "http://localhost:9991/engine-rest";
    private ExternalTaskClient client = null;

    //封装获取客户端的方法
    private ExternalTaskClient getClient(){
        if (ObjectUtil.isNull(client)){
            client = ExternalTaskClient.create()
                    .baseUrl(CAMUNDA_BASE_URL) //监听的camunda客户端(流程引擎端地址)
                    //long polling timeout
                    .asyncResponseTimeout(10000) //异步响应超时时间(轮询时间)
                    .build();
        }
        return client;
    }

    /**
     * Description:外部任务--订阅到加入购物车的任务节点执行
     * @param
     * @return void
    */
    @PostConstruct
    public void handleShoppingCart(){
        getClient().subscribe("shopping_cart") //客户端订阅【对应外部任务主题名称】
                .processDefinitionKey("Process_shopping") //流程定义Key(ID)
                .lockDuration(2000) //锁定外部任务时间
                .handler((externalTask, externalTaskService) -> {
                    log.info("333订阅到加入购物车任务");
                    //设置流程实例变量
                    Map<String,Object> goodVariable = Variables.createVariables()
                            .putValue("toWhere","shanghai China");
                    // 获取流程实例中已经存在的变量
                    String paramValue = externalTask.getVariable("param");
                    log.info("333shoppingCartId: {}", paramValue);
                    // 完成任务
                    externalTaskService.complete(externalTask,goodVariable);
                })
                .open();
    }
}
  • 外部任务实现方式二
    除了上述方式外,外部任务的实现方式还可以通过 camunda流程引擎提供的 @ExternalTaskSubscription 注解的方式来实现对应的 外部任务类。
package cn.zhidasifang.flowmanagement.camundaExternalClient.externalTask;

import com.sun.org.apache.xpath.internal.operations.Bool;
import org.camunda.bpm.client.spring.annotation.ExternalTaskSubscription;
import org.camunda.bpm.client.task.ExternalTaskHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName : SelfRepairService
 * @Description : 外部任务External的实现类Service
 * @Author : AD
 */

@Configuration
public class SelfRepairService {

    @Bean
    @ExternalTaskSubscription(
        	topicName = "try_self_repair"   //外部任务主题名称
            ,processDefinitionKeyIn = {"Process_external_task"} //流程实例定义Key
            ,lockDuration = 500000) //锁定外部任务时间
    public ExternalTaskHandler doSelfRepair(){
        return (externalTask, externalTaskService) -> {
            System.out.println("666外部任务进入尝试自修!");
            try {
                System.out.println("666线程睡眠5秒!");
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            Boolean isFree = (Boolean) externalTask.getVariable("isFree");
            if (isFree){
                System.out.println("666免费维修");
                externalTaskService.complete(externalTask);
            }else {
                System.out.println("666维修收费-尝试自修");
                externalTaskService.handleFailure(
                        externalTask
                        ,"自己修理,抛出异常中止后续上门维修!"
                        ,"这里可以打印一次stacktrace"
                        ,0   //为1会重复重试 为0会抛出异常信息
                        ,5000  //重新尝试时间,该时间段内不会被其它轮询获取到该任务
                );
            }
        };
    }
}

2.2 Java类实现 Java class

​ 外部任务在采用 Java class 方式实现时,需要在 Java class栏目中填写对应的Java类路径和类名称。
在这里插入图片描述
​ 当流程实例运行到对应的服务任务时,Camunda流程引擎会自动调用对应类路径下的java类。

​ 在对应的java类中,需要 实现 org.camunda.bpm.engine.delegate.JavaDelegate 同时重写 execute(DelegateExecution execution)方法,在流程引擎执行到对应的服务任务时,会自动执行该类中实现的 execute 方法。

​ 实例代码如下:在这里插入图片描述

2.3 表达式实现方式 Expression

​ 外部任务中,采用Expression表达式方式实现时,Expression栏目中需要填写的 就是UEL方法表达式,于前文 1.1中用户任务受理人设置的实现方式类似。

在这里插入图片描述
​ 当流程实例运行到该服务任务节点时,流程引擎会解析对应的UEL方法表达式 ${telCall.doCall(execution)} 。通过该表达式会调用 BeanName为 telCall的对象,同时调用该对象的doCall( ) 方法。

​ 需要注意,在使用 Expression 实现外部任务时,会存在 Result variable 返回值栏目 该栏目中设置对应返回值的Key值,在调用的对应对象方法中,需要返回对应数据。

​ 对应的代码实现部分示例如下:在这里插入图片描述

2.4 代理表达式 Delegate expression

​ 通过 Delegate expression 方式来实现的业务类,需要实现 JavaDelegate接口,并重写 execute 方法。 在Delegate expression栏目中使用UEL表达式将委派类对象填入即可。
在这里插入图片描述
​ 当流程实例执行到该节点时,流程引擎会自动调用对应 委派类对象实现的 execute 方法。

​ 委派类的实现代码如下:在这里插入图片描述

三、脚本任务 Script task

​ 脚本任务是一种自动执行的活动。当流程执行到脚本任务时,节点相关的脚本就会自动执行。

在这里插入图片描述

​ 脚本任务默认的类型有两种: 外部资源(External resource)、内部脚本(Inline script)

  • 内部脚本的方式实现
    在这里插入图片描述

    Script中的内容为:

//通过 execution 获取到流程实例中的流程变量
var person = execution.getVariable("name");
var originDays = execution.getVariable("originDays");
var leaveDay = execution.getVariable("leaveday");

//将设置的脚本执行结果Key直接赋值后会自动生成对应的流程实例变量记录存储到流程实例中
leftAnnualDays = originDays-leaveDay;

​ 内部脚本的方式会将填写的脚本内容会被追加到流程BPMN.xml中

在这里插入图片描述

  • 外部资源的方式实现

    外部资源的实现方式 和 内部脚本的区别在于 脚本内容不会追加到流程的BPMN.xml中。

    在这里插入图片描述

    在外部脚本的 Resource栏目中填写脚本的地址即可。

四、发送任务&接收任务

​ 发送任务(Send Task)一般用于发送一个消息;接收任务(Receive Task)一般用来等待发送任务的消息,起到等待作用。一般情况下发送任务和接收任务是成对配合使用的,同时是分开存在两个独立的流程模板中的。

  • 接收任务 Receive Task

    ​ 接收任务需要在Message栏目下配置,等待接收消息的 全局唯一名称。接收任务节点一旦启动之后,就会一直处于等待状态,知道接收到对应名称的截至,该接收任务就会结束。

    ​ 起到一个通讯作用,可以当作一个流程模板的触发器来使用,在接收任务后面继续添加其它类型的任务,当执行到接收任务处时,一直监听消息,当接收到消息后,就执行完成,在进行流程的后续操作!

    在这里插入图片描述

    注:需要先启动接收任务,处于监听等待状态后,发送任务才能成功的启动或者执行,否则流程引擎将会出现异常!

    ​ 无法关联消息" MessageName:xxxxx",没有进程定义或执行与参数匹配 !

    org.camunda.bpm.engine.MismatchingMessageCorrelationException: Cannot correlate message ‘Message_receive_task’: No process definition or execution matches the parameters

  • 发送任务 Send Task

    ​ 发送任务节点在流程设置器中的配置,Implementation项下可以配置发送任务的实现方式。发送任务的实现方式,在type选项栏下总共有5种:外部任务实现(External)、java类实现(Java class)、表达式实现(Expression)、代理表达式实现(Delegate expression)、Connector实现方式。

    ​ 这5种实现方式与服务任务(service task) 的采用形式一致,下面就以代理表达式(Delegate expression)的方式来实现发送任务。

    在这里插入图片描述

    ​ 在发送任务的实现代码中,需要指定业务标识BusinessKey 来确保只有对应的流程业务实例才能接收到该消息。 该业务标识指定的是 接收任务Receive Task所在的流程实例的业务标识 BusinessKey。

    ​ 在接收任务所在流程模板中,在启动流程实例时就可以对BusinessKey进行赋值,每个流程实例的业务标识代码都是自定义的,原理上是需要设置不同。在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/423024.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python】进阶学习:pandas--isin()用法详解

【Python】进阶学习&#xff1a;pandas–isin()用法详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订阅…

【java】20:枚举

枚举的二种实现方式 1) 自定义类实现枚举 2) 使用 enum 关键字实现枚举 自定义实现枚举&#xff1a; 1.不需要提供setXxx方法&#xff0c;因为枚举对象值通常为只读. 2.对枚举对象/属性使用final static共同修饰&#xff0c;实现底层优化. 3.枚举对象名通常使用全部大写&…

电子电气架构——汽车以太网诊断路由汇总

电子电气架构——汽车以太网诊断路由汇总 我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人们会在生活中不断攻击你。他们的主要武器是向你灌输对自己的怀疑:你的价值、你的能力、你的潜力。他们往往会将…

江科大stm32学习笔记——【4-1】OLED

一.原理 1.调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息。 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上。 Keil调试模式&#xff1a;借助Keil软件的调…

深入sizeof与strlen

一、sizeof与strlen的对比 sizeofstrlensizeof是单目操作符strlen是库函数&#xff0c;使用需要包含头文件string.hsizeof计算操作数所占用的内存&#xff0c;单位是字节strlen是求字符串长度&#xff0c;统计的是\0之前字符的个数不关注内存中存放什么数据 关注内存总是否有\0…

关于 HTTP 协议,你了解多少

HTTP协议 FastAPI 是建立在 HTTP 协议之上&#xff0c;所以为了更好的掌握 FastAPI。我们需要先简单的了解一下 HTTP协议 简介 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;遵循经典的客户端-服务器模型&#xff0c;客户端打开连接以发出请求&#xff0c;然后等…

Linux内核队列queue.h

文章目录 一、简介二、SLIST单向无尾链表2.1 介绍2.2 操作2.3 例子 三、STAILQ单向有尾链表四、LIST双向无尾链表五、TAILQ双向有尾链表六、CIRCLEQ循环链表七、queue源码参考 一、简介 queue.h是一个非常经典的文件&#xff0c;定义了一系列宏的操作&#xff0c;它定义了一系…

复盘昨天的内容

vue调节css 后端做业务处理 1.分类管理 GetMapping("/queryCtc")public ApiResult queryCtc(){return ctcService.queryCtc();}/*** 修改类目信息* return*/PutMapping("/updateCtc")public ApiResult updateCtc(RequestBody ShopCtc shopCtc){return c…

element-plus 的el-img组件访问oss图片自动拼接前端地址

这是我的组件代码 <el-image style"width: 100px; height: 100px" :src"scope.row.logo" />访问时候 竟然凭借上了前端的地址端口 原来是我的oss服务是使用了域名做cdn加速的 内容分发网络&#xff08;CDN&#xff09;或者服务器配置&#xff0c;可…

2.1 mov、add和sub加减指令实操体验

汇编语言 1. mov操作 1.1 mov移动值 mov指令把右边的值移动到左边 mount c d:masm c: debug r ax 0034 r 073f:0100 mov ax,7t1.2 mov移动寄存器的值 把右边寄存器的值赋值给左边的寄存器 a 073f:0105 mov bx,axt1.3 mov高八位&#xff08;high&#xff09;和低八位&am…

【leetcode】用栈实现队列

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家刷题&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 点击查看题目 思路: 在做此题之前&#xff0c;我们先要实现栈&#xff0c;这在上个博客中已经写过&#xf…

Topaz Gigapixel AI:让每一张照片都焕发新生mac/win版

Topaz Gigapixel AI 是一款革命性的图像增强软件&#xff0c;它利用先进的人工智能技术&#xff0c;能够显著提升图像的分辨率和质量。无论是摄影爱好者还是专业摄影师&#xff0c;这款软件都能帮助他们将模糊的、低分辨率的照片转化为清晰、细腻的高分辨率图像。 Topaz Gigap…

2024腾讯云优惠券领取和使用方法,北漂程序员整理

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

工会管理系统:繁琐工作,一套系统全搞定

hello&#xff0c;我是贝格前端工场&#xff0c;之前给大家介绍了各类通用的B端管理系统&#xff0c;受到了大家的欢迎。本次开始介绍针对具体行业的管理系统该如何设计和开发&#xff0c;欢迎大家持续关注、点赞&#xff0c;如有系统定制需求可以私信我们。 一、工会管理系统…

红外电力设施检测数据集

需要的同学私信联系&#xff0c;推荐关注上面图片右下角的订阅号平台 自取下载。 红外检测技术目标检测准确、速度快、涵盖面积广&#xff0c;可以在不停电、不接触、不解体、不采样的状态下&#xff0c;对带电设备的状态进行检测和诊断&#xff0c;精确查找出设备的劣化程度、…

蓝桥杯Java B组历年真题(2013年-2021年)

一、2013年真题 1、世纪末的星期 使用日期类判断就行&#xff0c;这里使用LocalDate&#xff0c;也可以使用Calendar类 答案 2099 使用LocalDate import java.time.LocalDate; import java.time.format.DateTimeFormatter; // 1:无需package // 2: 类名必须Main, 不可修改p…

【c++】VS2022静态库断点 “The breakpoint will not currently be hit. “

调试vs c++项目 :断点没符号加载 单独给使用的部分webrtc的源码构建了一个vs的静态库,给dll 用, 今天断点发现 No symbols have been loaded for this document.看到pdb lib 都有生成。但是就是断点提示:“The breakpoint will not currently be hit. No symbols have been…

赵文彬将出席无磷锅炉工艺助剂在锅炉水节水节能应用

演讲嘉宾&#xff1a;赵文彬 集团副总/技术总监 上远未来水务集团有限公司 演讲题目&#xff1a;无磷锅炉工艺助剂在锅炉水节水节能方面的应用 会议简介 “十四五”规划中提出&#xff0c;提高工业、能源领城智能化与信息化融合&#xff0c;明确“低碳经济”新的战略目标&a…

【SpringBoot】mybaitsPlus的多数据源配置

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;SpringBoot ⛺️稳重求进&#xff0c;晒太阳 mybatisPlus的多数据源配置 适用于多种场景&#xff1a;纯粹多库、 读写分离、 一主多从、 混合模式等 目前我们就来模拟一个纯粹多…

SpringCloud-同步异步通讯比较

本文详细探讨了同步通讯和异步通讯在信息传递中的区别&#xff0c;以及它们分别带来的优势和不足。通过对支付流程的案例分析&#xff0c;突显了同步通讯可能面临的阻塞和服务依赖问题&#xff0c;而异步通讯通过引入事件驱动模式和消息代理&#xff08;Broker&#xff09;成功…
最新文章