通过工厂模式实现SpringBoot+MQTT-订阅与消费

news2024/11/24 7:47:54

引言

Spring Boot 是一款用于构建基于 Spring 框架的快速应用程序的开源框架。它的目标是简化 Spring 应用程序的开发和部署过程,Spring Boot 通过提供一些默认配置和自动配置,可以让开发者更快的创建一个独立的、产品级别的 Spring 应用程序。

MQTT 是一种轻量级的消息传输协议,它被设计用于 IoT(物联网)中的低带宽和不可靠的网络环境中。MQTT 协议具有简单、开销小、可扩展等特点,非常适用于物联网场景。

本文将介绍如何使用 Spring Boot 和 MQTT 实现订阅与消费的功能,并通过工厂模式进行实现。

1. 准备工作

在开始本文的实现过程之前,我们需要准备一些环境和工具。

1.1 Spring Boot

首先,我们需要安装和配置 Spring Boot。在这里,我们将使用 Spring Initializr 工具来快速创建一个 Spring Boot 项目。您可以访问 https://start.spring.io/ 创建一个新的 Spring Boot 项目,也可以使用您自己的 IDE 或构建工具创建项目。

 

1.2 MQTT

接下来,我们需要使用 MQTT 客户端用来连接和通信 MQTT 服务器。在这里,我们将使用 Eclipse Paho MQTT 客户端库。您可以访问 https://www.eclipse.org/paho/clients/java/ 下载 Eclipse Paho MQTT 客户端库。

 

1.3 MQTT 服务器

最后,我们需要一个 MQTT 服务器。在这里,我们将使用 Eclipse Mosquitto 作为我们的 MQTT 服务器。您可以访问 https://mosquitto.org/ 下载和安装 Eclipse Mosquitto。

2.创建工厂类

我们将使用工厂模式来创建 MQTT 连接和订阅的对象。我们将创建一个 MQTTFactory 类来管理 MQTT 连接和订阅的对象。

2.1 创建 MQTTFactory 类

首先,我们创建一个 MQTTFactory 类。这个类将会是一个单例类,它将会负责管理 MQTT 连接和订阅的对象。我们使用静态块来初始化 MQTT 连接。

public class MQTTFactory {
    private static final String MQTT_SERVER_URL = "tcp://localhost:1883";
    private static final String MQTT_CLIENT_ID = "mqtt-client";
    private static final String MQTT_TOPIC = "mqtt-topic";

    private static MqttClient mqttClient;

    static {
        try {
            mqttClient = new MqttClient(MQTT_SERVER_URL, MQTT_CLIENT_ID);
            mqttClient.connect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    private static MQTTFactory instance;

    private MQTTFactory() {}

    public static MQTTFactory getInstance() {
        if (instance == null) {
            instance = new MQTTFactory();
        }
        return instance;
    }
}

在这个类中,我们定义了一些常量来设置 MQTT 服务器的地址、客户端 ID 和订阅的主题。在静态块中,我们使用 Eclipse Paho MQTT 客户端库创建了一个 MqttClient 对象,并连接到了 MQTT 服务器。在 getInstance() 方法中,我们使用懒汉式单例模式创建了一个 MQTTFactory 对象。

2.2 创建 MQTTSubscriber 类

接下来,我们创建一个 MQTTSubscriber 类来订阅 MQTT 主题。在 MQTTSubscriber 类中,我们定义了一个 subscribe() 方法,用于订阅 MQTT 主题。

public class MQTTSubscriber {
    private String topic;
    private MqttClient mqttClient;

    public MQTTSubscriber(String topic, MqttClient mqttClient) {
        this.topic = topic;
        this.mqttClient = mqttClient;
    }

    public void subscribe() throws MqttException {
        mqttClient.subscribe(topic, new IMqttMessageListener() {
            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                System.out.println(String.format("Received message: %s from topic: %s", new String(message.getPayload()), topic));
            }
        });
    }
}

在这个类中,我们使用构造方法来传递订阅的主题和 MQTT 客户端对象。在 subscribe() 方法中,我们使用 Eclipse Paho MQTT 客户端库的 subscribe() 方法来订阅 MQTT 主题。在 messageArrived() 方法中,我们使用 System.out.println() 方法来打印收到的消息。

3.创建 Spring Boot 应用程序

接下来,我们创建一个 Spring Boot 应用程序,来测试我们实现的 MQTT 订阅和消费的功能。

3.1 创建 Spring Boot 应用程序

我们可以使用 Spring Initializr 工具创建一个新的 Spring Boot 应用程序。在这里,我们创建一个名为 "mqtt-subscriber" 的应用程序。我们添加了如下的依赖:

  • spring-boot-starter-web
  • eclipse-paho-mqtt-client

在 pom.xml 文件中,我们添加了如下的依赖:

<dependency>
    <groupId>org.eclipse.paho</groupId>
    <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
    <version>1.2.5</version>
</dependency>

这个依赖用于引入 Eclipse Paho MQTT 客户端库。

3.2 创建 Spring Boot 控制器

我们创建一个名为 "MQTTSubscriberController" 的 Spring Boot 控制器。在这个控制器中,我们注入了一个 MQTTSubscriber 对象,并使用 @PostConstruct 注解来订阅 MQTT 主题。

@RestController
public class MQTTSubscriberController {
    private final MQTTSubscriber mqttSubscriber;

    public MQTTSubscriberController(MQTTSubscriber mqttSubscriber) {
        this.mqttSubscriber = mqttSubscriber;
    }

    @PostConstruct
    public void init() {
        try {
            mqttSubscriber.subscribe();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}

在 init() 方法中,我们调用了 MQTTSubscriber 的 subscribe() 方法来订阅 MQTT 主题。

3.3 测试应用程序

现在,我们可以启动应用程序并测试 MQTT 订阅和消费的功能了。我们可以使用 Eclipse Mosquitto 的命令行客户端来发布消息到订阅的主题中。

在命令行中,我们可以使用以下命令来发布消息:

mosquitto_pub -t myTopic -m "Hello, World!"

在这个命令中,我们使用 "mosquitto_pub" 命令行客户端来发布一条消息到 "myTopic" 主题中。消息内容为 "Hello, World!"。

如果一切正常,我们应该可以在控制台中看到如下的输出:

Received message: Hello, World! from topic: myTopic

这表明我们已经成功订阅并消费了 MQTT 主题中的消息。

4.总结

在本文中,我们使用工厂模式实现了一个 MQTT 订阅和消费的示例应用程序。我们使用 Eclipse Paho MQTT 客户端库来连接 MQTT 服务器,并订阅指定的主题。我们还使用 Spring Boot 框架来创建应用程序,并使用 @PostConstruct 注解来订阅 MQTT 主题。最后,我们使用 Eclipse Mosquitto 的命令行客户端来发布消息到订阅的主题中,并在控制台中查看已消费的消息。

 

5.进一步改进

在实际的应用程序中,我们可能需要进一步改进我们的实现。以下是一些可能的改进方案:

5.1 使用配置文件

在我们的示例应用程序中,我们硬编码了 MQTT 服务器的地址、端口号、订阅主题等信息。在实际的应用程序中,我们可能希望将这些信息放到配置文件中,以便在部署应用程序时能够轻松地修改这些信息。

我们可以在 application.properties 或 application.yml 文件中添加以下内容:

mqtt.server.host=mqtt.example.com
mqtt.server.port=1883
mqtt.topic=myTopic

然后,我们可以在 MQTTFactory 类中读取这些配置信息:

@Configuration
public class MQTTConfig {
    @Value("${mqtt.server.host}")
    private String mqttServerHost;

    @Value("${mqtt.server.port}")
    private int mqttServerPort;

    @Value("${mqtt.topic}")
    private String mqttTopic;

    @Bean
    public MqttClient mqttClient() throws MqttException {
        String brokerUrl = String.format("tcp://%s:%d", mqttServerHost, mqttServerPort);
        MqttClient mqttClient = new MqttClient(brokerUrl, MqttClient.generateClientId());
        mqttClient.connect();
        return mqttClient;
    }

    @Bean
    public MQTTSubscriber mqttSubscriber() throws MqttException {
        MqttClient mqttClient = mqttClient();
        return new MQTTSubscriber(mqttTopic, mqttClient);
    }

    @Bean
    public MQTTFactory mqttFactory() {
        return MQTTFactory.getInstance();
    }
}

现在,我们不再需要在代码中硬编码 MQTT 服务器的地址、端口号、订阅主题等信息,而是从配置文件中读取这些信息。

5.2 使用注解

在我们的示例应用程序中,我们使用 @PostConstruct 注解来订阅 MQTT 主题。在实际的应用程序中,我们可能希望使用更具有语义化的注解来标识哪些方法是用于订阅 MQTT 主题的。

我们可以定义一个 @MQTTSubscriber 注解,并在需要订阅 MQTT 主题的方法上使用该注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MQTTSubscriber {
}

然后,在 MQTTSubscriberController 类中,我们可以使用 @MQTTSubscriber 注解来标识订阅 MQTT 主题的方法:

@RestController
public class MQTTSubscriberController {
    private final MQTTSubscriber mqttSubscriber;

    public MQTTSubscriberController(MQTTSubscriber mqttSubscriber) {
        this.mqttSubscriber = mqttSubscriber;
    }

    @MQTTSubscriber
    public void onMessage(String topic, String message) {
        System.out.println(String.format("Received message: %s from topic: %s", message, topic));
    }
}

在这个例子中,我们定义了一个名为 "onMessage" 的方法,并使用 @MQTTSubscriber 注解来标识该方法是用于订阅 MQTT 主题的。在这个方法中,我们使用两个参数来接收收到的消息的主题和内容。

在我们的应用程序启动时,我们可以使用 Spring AOP 框架来自动扫描 @MQTTSubscriber 注解,并将被注解的方法注册为 MQTT 主题的订阅者。我们可以在 MQTTSubscriberAspect 类中实现这个功能:

@Aspect
@Component
public class MQTTSubscriberAspect {
    private final MQTTSubscriber mqttSubscriber;

    public MQTTSubscriberAspect(MQTTSubscriber mqttSubscriber) {
        this.mqttSubscriber = mqttSubscriber;
    }

    @PostConstruct
    public void subscribe() throws MqttException {
        MqttClient mqttClient = mqttSubscriber.getMqttClient();
        mqttClient.subscribe(mqttSubscriber.getTopic(), (topic, message) -> {
            String payload = new String(message.getPayload(), StandardCharsets.UTF_8);
            Object bean = mqttSubscriber.getBean();
            Method[] methods = bean.getClass().getMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(MQTTSubscriber.class) &&
                        method.getParameterCount() == 2 &&
                        method.getParameterTypes()[0].equals(String.class) &&
                        method.getParameterTypes()[1].equals(String.class)) {
                    method.setAccessible(true);
                    try {
                        method.invoke(bean, topic, payload);
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
}

在这个类中,我们使用 Spring AOP 框架的 @Aspect 注解来标识该类是一个切面类。在 @PostConstruct 方法中,我们获取 MQTT 订阅者的 MqttClient 实例,并使用该实例订阅指定的主题。然后,我们获取被注解的方法,并遍历这些方法,如果发现某个方法被标注为 @MQTTSubscriber,并且参数个数为 2,第一个参数为 String 类型,第二个参数也为 String 类型,则将该方法注册为订阅者。

现在,我们可以在任何需要订阅 MQTT 主题的方法上使用 @MQTTSubscriber 注解,而不必再使用 @PostConstruct 注解。这使得我们的代码更加具有语义化,并且更加容易阅读和维护。

6.结论

在本文中,我们使用工厂模式实现了一个 MQTT 订阅和消费的示例应用程序。我们使用 Eclipse Paho MQTT 客户端库来连接 MQTT 服务器,并订阅指定的主题。我们还使用 Spring Boot 框架来创建应用程序,并使用 @PostConstruct 注解来订阅 MQTT 主题。最后,我们介绍了使用配置文件和注解来改进我们的实现的方法。这些改进方案使我们的代码更加具有语义化,并且更加容易阅读和维护。

MQTT 是一种轻量级的消息传递协议,适用于物联网等场景中的消息传递。它具有简单、可靠、高效等特点,已经被广泛应用于各种场景中。使用工厂模式和 Spring Boot 框架来实现 MQTT 订阅和消费,可以使我们的代码更加清晰和易于维护。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pathon Django的关系映射

一对一 【创建】 一对一是表示现实事物间存在的一对一的对应关系。特殊字段选项 【必须】 on_delete - 级联删除 更多参考模型字段参考 | Django 文档 | Django使用oto示例&#xff1a; 1、先创建oto应用&#xff0c;然后到setting.py文件注册应用2、创建oto模型类3、创建…

【人工智能 AI】机器学习快速入门教程(Google)

目录 机器学习术语 标签 特性 示例 模型 回归与分类 深入了解机器学习&#xff1a;线性回归 深入了解机器学习&#xff1a;训练和损失 平方损失函数&#xff1a;一种常用的损失函数 机器学习术语 预计用时&#xff1a;8 分钟 什么是&#xff08;监督式&#xff…

蚁群算法再优化:combine aco algorithm with Sarsa in RL

蚁群算法再优化&#xff1a;combine aco algorithm with Sarsa in RL蚁群算法、Sarsa介绍和TSP问题介绍TSP和Sarsaaco algorithm具体的改进和代码改进说明部分代码数值实验结论分析参考文献蚁群算法、Sarsa介绍和TSP问题介绍 在进行蚁群算法优化介绍之前&#xff0c;笔者先将涉…

Apache Pulsar 云原生消息中间件之王

一、简介 pulsar&#xff0c;消息中间件&#xff0c;是一个用于服务器到服务器的消息系统&#xff0c;具有多租户、高性能等优势。 pulsar采用发布-订阅的设计模式&#xff0c;producer发布消息到topic&#xff0c;consumer订阅这些topic处理流入的消息&#xff0c;并当处理完…

OIDC OAuth2.0 认证协议最佳实践系列 02 - 授权码模式(Authorization Code)接入 Authing

在上一篇文章OIDC & OAuth2.0 认证协议最佳实践系列 02 - 授权码模式&#xff08;Authorization Code&#xff09;接入 Authing中&#xff0c;我们整体介绍 OIDC / OAuth2.0 协议&#xff0c;本次我们将重点围绕授权码模式&#xff08;Authorization Code&#xff09;以及接…

RabbitMQ第一讲

目录 一、RabbitMQ-01 1.1 MQ概述 1.2 MQ的优势和劣势 1.2.1 优势 1.2.2 劣势 1.2.3 MQ应用场景 1.2.4 常用的MQ产品 1.3 RabbitMQ的基本介绍 1.3.1 AMQP介绍 1.3.2 RabbitMQ基础架构 1.3.3 RabbitMQ的6种工作模式 ​编辑 1.4 AMQP和JMS 1.4.1 AMQP 1.4.2 JMS …

00后跨专业学软件测试,斩获8.5K高薪逆袭职场

我想说的第一句&#xff1a;既然有梦想&#xff0c;就应该去拼搏还记得&#xff0c;我大学毕业前&#xff0c;就已经暗下决心到xxx培训机构接受培训。那个时候&#xff0c;没有任何海同公司的人主动找我或者联系过我&#xff0c;我是自己在网上发现了xxxx培训机构的&#xff01…

PLC实验—西门子S7 1200 PID控制步进电机转速

PLC实验—西门子S7 1200 PID控制步进电机转速 严格讲并不是PID控制&#xff0c;因为并不是并不研究这个方向&#xff0c;研二又比较忙&#xff0c;时间限制只加了比例系数 这里只是抛砖引玉&#xff0c;希望大家可以进一步完善补充 思路 大体思路如下&#xff0c;根据超声波…

三八节买什么数码好物?三八女神节实用不吃灰的数码好物推荐

三八节快到了&#xff0c;在这个小节日里&#xff0c;有哪些实用性强的数码好物值得入手呢&#xff1f;针对这个问题&#xff0c;我来给大家推荐几款实用性超强的数码好物&#xff0c;一起来看看吧。 一、蓝牙耳机 推荐产品&#xff1a;南卡小音舱 参考价&#xff1a;239 南…

Python中Opencv和PIL.Image读取图片的差异对比

近日&#xff0c;在进行深度学习进行推理的时候&#xff0c;发现不管怎么样都得不出正确的结果&#xff0c;再仔细和正确的代码进行对比了后发现原来是Python中不同的库读取的图片数组是有差异的。 image np.array(Image.open(image_file).convert(RGB)) image cv2.imread(…

【持续学习引导:pansharpening】

A continual learning-guided training framework for pansharpening &#xff08;一种持续学习引导的全色锐化训练框架&#xff09; 基于监督学习的全色锐化方法自出现以来一直受到批评&#xff0c;因为它们依赖于尺度移位假设&#xff0c;即这些方法在降低分辨率时的性能通…

IntelliJ IDEA如何整合Maven图文教程详解

Maven 1.Maven简述 Maven是一个构建工具,服务与构建.使用Maven配置好项目后,输入简单的命令,如:mvn clean install,Maven会帮我们处理那些繁琐的任务. Maven是跨平台的. Maven最大化的消除了构建的重复. Maven可以帮助我们标准化构建过程.所有的项目都是简单一致的,简化了学习…

ChatGPT能完全取代软件开发吗,看看它怎么回答?

最近网上一直疯传&#xff0c;ChatGPT 最可能取代的 10 种工作。具体包括①、技术类工作&#xff1a;程序员、软件工程师、数据分析师②、媒体类工作&#xff1a;广告、内容创作、技术写作、新闻③、法律类工作&#xff1a;法律或律师助理④、市场研究分析师⑤、教师⑥、金融类…

如何提高推广邮件的发送成功率?

随着经济的发展&#xff0c;国际之间的贸易往来越加频繁&#xff0c;很多外贸企业需要发送大量的商业推广邮件&#xff0c;来获得销售订单开拓公司业务市场。 随之而来的问题也是越来越多&#xff0c;给众多的外贸企业带来诸多的困扰。外贸企业在发送推广邮件中究竟会遇到什么问…

2.4G收发一体芯片NRF24L01P跟国产软硬件兼容 SI24R1对比

超低功耗高性能 2.4GHz GFSK 无线收发器芯片Si24R1&#xff0c;软硬件兼容NRF24L01P. Si24R1 是一颗工作在 2.4GHz ISM 频段&#xff0c;专为低功耗无线场合设计&#xff0c;集成嵌入式ARQ 基带协议引擎的无线收发器芯片。工作频率范围为 2400MHz-2525MHz&#xff0c;共有 126个…

Nginx网络服务

目录 1.Nginx基础 1.Nginx和Apache的差异 2.Nginx和Apache的优缺点比较 3.编译安装nginx服务 2.认识Nginx服务的主配置文件 nginx.conf 1.全局配置 2.I/O事件配置 3.HTTP设置 4.访问状态统计配置 5.基于授权密码的访问控制 6.基于客户端的访问控制 7.基于域名的ng…

SpringCloud简单介绍

文章目录1. 开源组件2. CAP原则1. 开源组件 功能springcloud netflixspringcloud alibabaspringcloud官方其他服务注册与发现eurekanacosconsulzookeeper负载均衡ribbondubbo服务调用openFeigndubbo服务容错hystrixsentinel服务网关zuulgateway服务配置的同一管理cofig-server…

图论初入门

目录 一、前言 二、图的概念 三、例题及相关概念 1、全球变暖&#xff08;2018年省赛&#xff0c;lanqiao0J题号178&#xff09; 2、欧拉路径 3、小例题 4、例题&#xff08;洛谷P7771&#xff09; 一、前言 本文主要讲了树与图的基本概念&#xff0c;图的存储、DFS遍历…

pytorch训练第一个项目VOC2007分割

一、环境 condapytorch1.2.0cuda10.0pycharm 二、训练内容 数据集&#xff1a;VOC2007 网络&#xff1a;U-net 功能&#xff1a;分割图像分类 三、步骤 安装软件、框架、包、cuda&#xff08;不安用cpu跑也可以&#xff09;&#xff0c;下载数据集、代码、权重文件等。。…

测试外包干了5年,感觉自己已经废了····

前两天有读者想我资讯&#xff1a; 我是一名软件测试工程师&#xff0c;工作已经四年多快五年了。现在正在找工作&#xff0c;由于一直做的都是外包的项目。技术方面都不是很深入&#xff0c;现在找工作都是会问一些&#xff0c;测试框架&#xff0c;自动化测试&#xff0c;感…