springboot+rabbitmq实现智能家居实例详解

目录
  • 引言
  • 一、什么是 MQTT协议?
  • 二、为什么要用 MQTT协议?
  • 三、MQTT协议介绍
    • MQTT数据包
    • 1、固定头
    • 2、可变头
    • 3、消息体payload
    • 消息质量(QoS )
    • 1、Qos 0
    • 2、Qos 1
    • 3、Qos 2
    • LWT(最后遗嘱)
  • 四、MQTT协议应用场景
  • 五、代码实现
    • 1、启用 rabbitmq的mqtt协议
    • 2、mqtt 客户端依赖包
    • 3、消息发送者
    • 4、消息订阅
  • 六、测试消息
    • 1、测试消息发送
    • 2、测试消息订阅
  • 七、应用注意事项
    • clientId 要唯一
  • 八、其他中间件
  • 总结

引言

前一段有幸参与到一个智能家居项目的开发,由于之前都没有过这方面的开发经验,所以对智能硬件的开发模式和技术栈都颇为好奇。

智能可燃气体报警器

产品是一款可燃气体报警器,如果家中燃气泄露浓度到达一定阈值,报警器检测到并上传气体浓度值给后台,后台以电话、短信、微信等方式,提醒用户家中可能有气体泄漏。

用户还可能向报警器发一些关闭报警、调整音量的指令等。整体功能还是比较简单的,大致的逻辑如下图所示:

但当我真正的参与其中开发时,其实有一点小小的失望,因为在整个研发过程中,并没用到什么新的技术,还是常规的几种中间件,只不过换个用法而已。

技术选型用rabbitmq 来做核心的组件,主要考虑到运维成本低,组内成员使用的熟练度比较高。

下面和小伙伴分享一下如何用 springboot + rabbitmq 搭建物联网(IOT)平台,其实智能硬件也没想象的那么高不可攀!

很多小伙伴可能有点懵?rabbitmq 不是消息队列吗?怎么又能做智能硬件了

其实rabbitmq有两种协议,我们平时接触的消息队列是用的AMQP协议,而用在智能硬件中的是MQTT协议。

一、什么是 MQTT协议?

MQTT 全称(Message Queue Telemetry Transport):一种基于发布/订阅(publish/subscribe)模式的轻量级通讯协议,通过订阅相应的主题来获取消息,是物联网(Internet of Thing)中的一个标准传输协议。

该协议将消息的发布者(publisher)与订阅者(subscriber)进行分离,因此可以在不可靠的网络环境中,为远程连接的设备提供可靠的消息服务,使用方式与传统的MQ有点类似。

TCP协议位于传输层,MQTT 协议位于应用层,MQTT 协议构建于TCP/IP协议上,也就是说只要支持TCP/IP协议栈的地方,都可以使用MQTT协议。

二、为什么要用 MQTT协议?

MQTT协议为什么在物联网(IOT)中如此受偏爱?而不是其它协议,比如我们更为熟悉的 HTTP协议呢?

  • 首先HTTP协议它是一种同步协议,客户端请求后需要等待服务器的响应。而在物联网(IOT)环境中,设备会很受制于环境的影响,比如带宽低、网络延迟高、网络通信不稳定等,显然异步消息协议更为适合IOT应用程序。
  • HTTP是单向的,如果要获取消息客户端必须发起连接,而在物联网(IOT)应用程序中,设备或传感器往往都是客户端,这意味着它们无法被动地接收来自网络的命令。
  • 通常需要将一条命令或者消息,发送到网络上的所有设备上。HTTP要实现这样的功能不但很困难,而且成本极高。

三、MQTT协议介绍

前边说过MQTT是一种轻量级的协议,它只专注于发消息, 所以此协议的结构也非常简单。

MQTT数据包

MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、 可变头(Variable header)、 消息体(payload)三部分构成。

  • 固定头(Fixed header),所有数据包中都有固定头,包含数据包类型及数据包的分组标识。
  • 可变头(Variable header),部分数据包类型中有可变头。
  • 内容消息体(Payload),存在于部分数据包类,是客户端收到的具体消息内容。

在这里插入图片描述

1、固定头

固定头部,使用两个字节,共16位:

(4-7)位表示消息类型,使用4位二进制表示,可代表如下的16种消息类型,不过 0 和 15位置属于保留待用,所以共14种消息事件类型。

DUP Flag(重试标识)

DUP Flag:保证消息可靠传输,消息是否已送达的标识。默认为0,只占用一个字节,表示第一次发送,当值为1时,表示当前消息先前已经被传送过。

QoS Level(消息质量等级)

QoS Level:消息的质量等级,后边会详细介绍

RETAIN(持久化)

  • 值为1:表示发送的消息需要一直持久保存,而且不受服务器重启影响,不但要发送给当前的订阅者,且以后新加入的客户端订阅了此Topic,订阅者也会马上得到推送。注意:新加入的订阅者,只会取出最新的一个RETAIN flag = 1的消息推送。
  • 值为0:仅为当前订阅者推送此消息。

Remaining Length(剩余长度)

在当前消息中剩余的byte(字节)数,包含可变头部和消息体payload。

2、可变头

固定头部仅定义了消息类型和一些标志位,一些消息的元数据需要放入可变头部中。可变头部内容字节长度 + 消息体payload = 剩余长度。

可变头部居于固定头部和payload中间,包含了协议名称,版本号,连接标志,用户授权,心跳时间等内容。

可变头存在于这些类型的消息:PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。

3、消息体payload

消息体payload只存在于CONNECTPUBLISHSUBSCRIBESUBACKUNSUBSCRIBE这几种类型的消息:

  • CONNECT:包含客户端的ClientId、订阅的TopicMessage以及用户名密码
  • PUBLISH:向对应主题发送消息。
  • SUBSCRIBE:要订阅的主题以及QoS
  • SUBACK:服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。
  • UNSUBSCRIBE:取消要订阅的主题。

消息质量(QoS )

消息质量(Quality of Service),即消息的发送质量,发布者(publisher)和订阅者(subscriber)都可以指定qos等级,有QoS 0QoS 1QoS 2三个等级。

下边分别说明一下这三个等级的区别。

1、Qos 0

Qos 0:At most once(至多一次)只发送一次消息,不保证消息是否成功送达,没有确认机制,消息可能会丢失或重复。

图片源于网络,如有侵权联系删除

2、Qos 1

Qos 1:At least once(至少一次),相对于QoS 0而言Qos 1增加了ack确认机制,发送者(publisher)推送消息到MQTT代理(broker)时,两者自身都会先持久化消息,只有当publisher 或者 Broker分别收到 PUBACK确认时,才会删除自身持久化的消息,否则就会重发。

但有个问题,尽管我们可以通过确认来保证一定收到客户端 或 服务器的message,可我们却不能保证仅收到一次message,也就是当客户端publisher没收到Brokerpuback或者 Broker没有收到subscriberpuback,那么就会一直重发。

publisher -> broker 大致流程:

publisher store msg -> publish ->broker (传递message)

broker -> puback -> publisher delete msg (确认传递成功)

图片源于网络,如有侵权联系删除

3、Qos 2

Qos 2:Exactly once(只有一次),相对于QoS 1QoS 2升级实现了仅接受一次messagepublisher 和 broker 同样对消息进行持久化,其中 publisher 缓存了message和 对应的msgID,而 broker 缓存了 msgID,可以保证消息不重复,由于又增加了一个confirm 机制,整个流程变得复杂很多。

publisher -> broker 大致流程:

publisher store msg -> publish ->broker -> broker store

msgID(传递message) broker -> puberc (确认传递成功)

publisher -> pubrel ->broker delete msgID (告诉broker删除msgID)

broker -> pubcomp -> publisher delete msg (告诉publisher删除msg)

LWT(最后遗嘱)

LWT 全称为 Last Will and Testament,其实遗嘱是一个由客户端预先定义好的主题和对应消息,附加在CONNECT的数据包中,包括遗愿主题遗愿 QoS遗愿消息等。

当MQTT代理 Broker 检测到有客户端client非正常断开连接时,再由服务器主动发布此消息,然后相关的订阅者会收到消息。

举个栗子:聊天室中所有人都订阅一个叫talk的主题 ,但小富由于网络抖动突然断开了链接,这时聊天室中所有订阅主题 talk的客户端都会收到一个 “小富离开聊天室” 的遗愿消息。

遗嘱的相关参数:

Will Flag:是否使用 LWT,1 开启

Will Topic:遗愿主题名,不可使用通配符

Will Qos:发布遗愿消息时使用的 QoS

Will Retain:遗愿消息的 Retain 标识

Will Message:遗愿消息内容

那客户端Client 有哪些场景是非正常断开连接呢?

  • Broker 检测到底层的 I/O 异常;
  • 客户端 未能在心跳 Keep Alive 的间隔内和 Broker 进行消息交互;
  • 客户端 在关闭底层 TCP 连接前没有发送 DISCONNECT 数据包;
  • 客户端 发送错误格式的数据包到 Broker,导致关闭和客户端的连接等。

注意:当客户端通过发布 DISCONNECT 数据包断开连接时,属于正常断开连接,并不会触发 LWT 的机制,与此同时Broker 还会丢弃掉当前客户端在连接时指定的相关 LWT 参数。

四、MQTT协议应用场景

MQTT协议广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等领域。使用的场景也是非常非常多,下边列举一些:

  • 物联网M2M通信,物联网大数据采集
  • Android消息推送,WEB消息推送
  • 移动即时消息,例如Facebook Messenger
  • 智能硬件、智能家具、智能电器
  • 车联网通信,电动车站桩采集
  • 智慧城市、远程医疗、远程教育
  • 电力、石油与能源等行业市场

五、代码实现

具体 rabbitmq 的环境搭建就不赘述了,网上教程比较多,有条件的用服务器,没条件的像我搞个Windows版的也很快乐嘛。

在这里插入图片描述

1、启用 rabbitmq的mqtt协议

我们先开启 rabbitmq 的 mqtt协议,因为默认安装下是关闭的,命令如下:

rabbitmq-plugins enable rabbitmq_mqtt

2、mqtt 客户端依赖包

上一步中安装rabbitmq环境并开启 mqtt协议后,实际上mqtt 消息代理服务就搭建好了,接下来要做的就是实现客户端消息的推送和订阅。

这里使用spring-integration-mqttorg.eclipse.paho.client.mqttv3两个工具包实现。

<!--mqtt依赖包-->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
    <groupId>org.eclipse.paho</groupId>
       <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
    <version>1.2.0</version>
</dependency>

3、消息发送者

消息的发送比较简单,主要是应用到@ServiceActivator注解,需要注意messageHandler.setAsync属性,如果设置成false,关闭异步模式发送消息时可能会阻塞。

@Configuration
public class IotMqttProducerConfig {

    @Autowired
    private MqttConfig mqttConfig;

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setServerURIs(mqttConfig.getServers());
        return factory;
    }

    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }

    @Bean
    @ServiceActivator(inputChannel = "iotMqttInputChannel")
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(mqttConfig.getServerClientId(), mqttClientFactory());
        messageHandler.setAsync(false);
        messageHandler.setDefaultTopic(mqttConfig.getDefaultTopic());
        return messageHandler;
    }
}

MQTT 对外提供发送消息的API时,需要使用@MessagingGateway 注解,去提供一个消息网关代理,参数defaultRequestChannel 指定发送消息绑定的channel

可以实现三种API接口,payload 为发送的消息,topic 发送消息的主题,qos 消息质量。

@MessagingGateway(defaultRequestChannel = "iotMqttInputChannel")
public interface IotMqttGateway {

    // 向默认的 topic 发送消息
    void sendMessage2Mqtt(String payload);
    // 向指定的 topic 发送消息
    void sendMessage2Mqtt(String payload,@Header(MqttHeaders.TOPIC) String topic);
    // 向指定的 topic 发送消息,并指定服务质量参数
    void sendMessage2Mqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
}

4、消息订阅

消息订阅和我们平时用的MQ消息监听实现思路基本相似,@ServiceActivator注解表明当前方法用于处理MQTT消息,inputChannel 参数指定了用于接收消息的channel

/**
 * @Author: xiaofu
 * @Description: 消息订阅配置
 * @date 2020/6/8 18:24
 */
@Configuration
public class IotMqttSubscriberConfig {

    @Autowired
    private MqttConfig mqttConfig;

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setServerURIs(mqttConfig.getServers());
        return factory;
    }

    @Bean
    public MessageChannel iotMqttInputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageProducer inbound() {
        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(mqttConfig.getClientId(), mqttClientFactory(), mqttConfig.getDefaultTopic());
        adapter.setCompletionTimeout(5000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        adapter.setOutputChannel(iotMqttInputChannel());
        return adapter;
    }

    /**
     * @author xiaofu
     * @description 消息订阅
     * @date 2020/6/8 18:20
     */
    @Bean
    @ServiceActivator(inputChannel = "iotMqttInputChannel")
    public MessageHandler handlerTest() {

        return message -> {
            try {
                String string = message.getPayload().toString();
                System.out.println("接收到消息:" + string);
            } catch (MessagingException ex) {
                //logger.info(ex.getMessage());
            }
        };
    }
}

六、测试消息

额~ 由于本渣渣对硬件一窍不通,为了模拟硬件的发送消息,只能借助一下工具,其实硬件端实现MQTT协议,跟我们前边的基本没什么区别,只不过换种语言嵌入到硬件中而已。

这里选的测试工具为mqttbox,下载地址:http://workswithweb.com/mqttbox.html

1、测试消息发送

我们用先用mqttbox模拟向主题mqtt_test_topic发送消息,看后台是否能成功接收到。

看到后台成功拿到了向主题mqtt_test_topic发送的消息。

2、测试消息订阅

mqttbox模拟订阅主题mqtt_test_topic,在后台向主题mqtt_test_topic发送一条消息,这里我简单的写了个controller调用API发送消息。

http://127.0.0.1:8080/fun/testMqtt?topic=mqtt_test_topic&message=我是后台向主题 mqtt_test_topic 发送的消息

我们看mqttbox的订阅消息,已经成功的接收到了后台的消息,到此我们的MQTT通信环境就算搭建成功了。如果把mqttbox工具换成具体硬件设备,整个流程就是我们常说的智能家居了,其实真的没那么难。

七、应用注意事项

在我们实际的生产环境中遇到过的问题,这里分享一下让大家少踩坑。

clientId 要唯一

在客户端connect连接的时,会有一个clientId 参数,需要每个客户端都保持唯一的。但我们在开发测试阶段clientId直接在代码中写死了,而且服务都是单实例部署,并没有暴露出什么问题。

MqttPahoMessageDrivenChannelAdapter(mqttConfig.getClientId(), mqttClientFactory(), mqttConfig.getDefaultTopic());

然而在生产环境内侧的时候,由于服务是多实例集群部署,结果出现了下边的奇怪问题。同一时间内只能有一个客户端能拿到消息,其他客户端不但不能消费消息,而且还在不断的掉线重连:Lost connection: 已断开连接; retrying...

这就是由于clientId相同导致客户端间相互竞争消费,最后将clientId获取方式换成从发号器中拿,问题就好了,所以这个地方是需要特别注意的。

平时程序在开发环境没问题,可偏偏到了生产环境就一大堆问题,很多都是因为服务部署方式不同导致的。所以多学习分布式还是很有必要的。

八、其他中间件

MQTT它只是一种协议,支持MQTT协议的消息中间件产品非常多,下边的也只是其中的一部分

  • Mosquitto
  • Eclipse Paho
  • RabbitMQ
  • Apache ActiveMQ
  • HiveMQ
  • JoramMQ
  • ThingMQ
  • VerneMQ
  • Apache Apollo
  • emqttd Xively
  • IBM Websphere .....

总结

我也是第一次做和硬件相关的项目,之前听到智能家居都会觉得好高大上,但实际上手开发后发现,技术嘛万变不离其宗,也只是换种用法而已。

以上就是springboot+rabbitmq实现智能家居实例详解的详细内容,更多关于springboot rabbitmq智能家居的资料请关注我们其它相关文章!

(0)

相关推荐

  • springboot+rabbitmq实现指定消费者才能消费的方法

    如何保证mq队列里的消息只被测试服务器上的consumer消费,避免本地环境误消费? 程序里有一个应用场景使用到了rabbitmq--当财务确认收到企业的打款金额后,系统会把企业订单生成用户付款单.由于订单记录数据量大,改为通过mq来异步实现.即财务确认收款操作后,将企业订单数据放入mq,另一端监听mq消息队列,将收到的企业订单加工转换成用户付款单,并做持久化. 本地开发环境与测试环境共用一套rabbitmq.当项目部署到测试环境后,QA测试过程中,总是"莫名其妙"的发现所保存的用户付

  • SpringBoot+RabbitMQ+Redis实现商品秒杀的示例代码

    目录 业务分析 创建表 功能实现 1.用户校验 2.下单 3.减少库存 4.支付 总结 业务分析 一般而言,商品秒杀大概可以拆分成以下几步: 用户校验 校验是否多次抢单,保证每个商品每个用户只能秒杀一次 下单 订单信息进入消息队列,等待消费 减少库存 消费订单消息,减少商品库存,增加订单记录 付款 十五分钟内完成支付,修改支付状态 创建表 goods_info 商品库存表 列 说明 id 主键(uuid) goods_name 商品名称 goods_stock 商品库存 package com.

  • 详解SpringBoot整合RabbitMQ如何实现消息确认

    目录 简介 生产者消息确认 介绍 流程 配置 ConfirmCallback ReturnCallback 注册ConfirmCallback和ReturnCallback 消费者消息确认 介绍 手动确认三种方式 简介 本文介绍SpringBoot整合RabbitMQ如何进行消息的确认. 生产者消息确认 介绍 发送消息确认:用来确认消息从 producer发送到 broker 然后broker 的 exchange 到 queue过程中,消息是否成功投递. 如果消息和队列是可持久化的,那么确认消

  • SpringBoot中RabbitMQ集群的搭建详解

    目录 1. 两种模式 1.1 普通集群 1.2 镜像集群 1.3 节点类型 2. 搭建普通集群 2.1 预备知识 2.2 开始搭建 2.3 代码测试 2.4 反向测试 3. 搭建镜像集群 3.1 网页配置镜像队列 3.2 命令行配置镜像队列 4. 小结 单个的 RabbitMQ 肯定无法实现高可用,要想高可用,还得上集群. 今天松哥就来和大家聊一聊 RabbitMQ 集群的搭建. 1. 两种模式 说到集群,小伙伴们可能第一个问题是,如果我有一个 RabbitMQ 集群,那么是不是我的消息集群中的

  • springboot2.5.6集成RabbitMq实现Topic主题模式(推荐)

    1.application.yml server: port: 8184 spring: application: name: rabbitmq-demo rabbitmq: host: 127.0.0.1 # ip地址 port: 5672 username: admin # 连接账号 password: 123456 # 连接密码 template: retry: enabled: true # 开启失败重试 initial-interval: 10000ms # 第一次重试的间隔时长 ma

  • 详解SpringBoot中使用RabbitMQ的RPC功能

    一.RabbitMQ的RPC简介 实际业务中,有的时候我们还需要等待消费者返回结果给我们,或者是说我们需要消费者上的一个功能.一个方法或是一个接口返回给我们相应的值,而往往大型的系统软件,生产者跟消费者之间都是相互独立的两个系统,部署在两个不同的电脑上,不能通过直接对象.方法的形式获取想要的结果,这时候我们就需要用到RPC(Remote Procedure Call)远程过程调用方式. RabbitMQ实现RPC的方式很简单,生产者发送一条带有标签(消息ID(correlation_id)+回调

  • springboot+rabbitmq实现智能家居实例详解

    目录 引言 一.什么是 MQTT协议? 二.为什么要用 MQTT协议? 三.MQTT协议介绍 MQTT数据包 1.固定头 2.可变头 3.消息体payload 消息质量(QoS ) 1.Qos 0 2.Qos 1 3.Qos 2 LWT(最后遗嘱) 四.MQTT协议应用场景 五.代码实现 1.启用 rabbitmq的mqtt协议 2.mqtt 客户端依赖包 3.消息发送者 4.消息订阅 六.测试消息 1.测试消息发送 2.测试消息订阅 七.应用注意事项 clientId 要唯一 八.其他中间件

  • IntelliJ Idea SpringBoot 数据库增删改查实例详解

    SpringBoot 是 SpringMVC 的升级,对于编码.配置.部署和监控,更加简单 微服务 微服务是一个新兴的软件架构,就是把一个大型的单个应用程序和服务拆分为数十个的支持微服务.一个微服务的策略可以让工作变得更为简便,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议. Spring 为 微服务提供了一整套的组件-SpringClound , SpirngBoot 就是该基础. 第一个SpringBoot程序 这里使用的开发软件是IntelliJ Idea,和Eclipse

  • SpringBoot使用WebSocket的方法实例详解

    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输. 在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道.两者之间就直接可以数据互相传送. java怎么写 配置Be

  • 使用SpringBoot整合ssm项目的实例详解

    SpringBoot是什么? Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程. Spring Boot 现在已经成为 Java 开发领域的一颗璀璨明珠,它本身是包容万象的,可以跟各种技术集成.成为 SpringBoot 全家桶,成为一把万能钥匙. SpringBoot的特点 1.创建独立的 Spring 应用程序 2.嵌入的 Tomcat ,无需部署 WAR 文件 3.简化 Maven 配置 4.自动配置 Spr

  • springboot单元测试两种方法实例详解

    这篇文章主要介绍了springboot单元测试两种方法实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 springboot的单元测试,这里介绍两种方式,一种是在测试类中添加注解:另一种是在代码中启动项目的main方法中继承接口(也可以写在其他方法中). 如 对查看数据库的连接池信息 进行单元测试 1. 在类上使用注解: @RunWith(SpringRunner.class) @SpringBootTest @RunWith(Sprin

  • SpringBoot+RabbitMQ实现消息可靠传输详解

    目录 环境配置 消息丢失分析 生产阶段 生产端模拟消息丢失 RabbitMQ 消费端 环境配置 SpringBoot 整合 RabbitMQ 实现消息的发送. 1.添加 maven 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <depen

  • SpringBoot Starter依赖原理与实例详解

    目录 1 Starter 2 了解 spring.factories机制 2.1 不同包路径下的依赖注入 2.2 spring.factories 机制 3 spring.factories 机制的实现源码分析 4 程序运行入口run() 1 Starter 在开发 SpringBoot 项目的时候,我们常常通过 Maven 导入自动各种依赖,其中很多依赖都是以 xxx-starter 命名的. 像这种 starter 依赖是怎么工作的呢? 2 了解 spring.factories机制 导入一

  • springboot+dubbo+zookeeper的简单实例详解

    目录 服务端 消费端 在dubbo-admin-0.0.1-SNAPSHOT.jar的路径下启动dubbo,java -jar dubbo-admin-0.0.1-SNAPSHOT.jar dubbo-admin-0.0.1-SNAPSHOT.jar的包需要提前打好 启动zookeeper的zkServer.cmd和zkCli.cmd 需要的依赖 <!-- 导入依赖:zookeeper + dubbo --> <!-- https://mvnrepository.com/artifact

  • C++智能指针实例详解

    本文通过实例详细阐述了C++关于智能指针的概念及用法,有助于读者加深对智能指针的理解.详情如下: 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见. 用智能指针便可以有效缓解这类问题,本文主要讲解参见的智能指针的用法.包括:std::auto_ptr.boost::scoped_ptr.boost::shared_p

  • SpringBoot如何进行业务校验实例详解

    目录 前言 为什么需要Assert? 如何使用Assert? 加入全局异常拦截器 常见的Assert使用场景 小结 总结 前言 今天继续来聊聊在SpringBoot项目中如何实现业务异常校验Assert. 希望通过今天的文章,咱们能够了解到: 如何使用Assert参数校验? 为什么用了Validator参数校验,还必须再用Assert参数校验? 首先我们来看看为什么需要Assert? 为什么需要Assert? Assert翻译为中文为"断言",它是spring的一个util类,org.

随机推荐