java客户端使用MQTT订阅消息大致流程

  1. 首先通过消息服务器节点的地址,new 一个MqttClient连接对象然后给MqttClient设置回调。
  2. 这里是通过new 一个MqttCallback对象(注入失败问题就在这) 来实现对topic中消息的监听和处理,所以服务端的处理心跳消息的主要业务逻辑均在MqttCallback实例中的messageArrived方法中。
  3. 建立连接。
  4. 订阅topic。

MQTTConnect部分代码

    /**
* 客户端connect连接mqtt服务器
*
* @param mqttCallback 回调函数
**/
public void setMqttClient(MqttCallback mqttCallback) throws MqttException {
MqttConnectOptions options = mqttConnectOptions(USER_NAME, PASS_WORD);
mqttClient.setCallback(mqttCallback);
mqttClient.connect(options);
} /**
* MQTT连接参数设置
*/
private MqttConnectOptions mqttConnectOptions(String userName, String passWord) throws MqttException {
mqttClient = new MqttClient(HOST, clientId, new MemoryPersistence());
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(userName);
options.setPassword(passWord.toCharArray());
options.setConnectionTimeout(10);///默认:30
options.setAutomaticReconnect(true);//默认:false
options.setCleanSession(false);//默认:true
//options.setKeepAliveInterval(20);//默认:60
return options;
}

MQTTListener部分代码

/**
* 这里采用了自定义一个ApplicationListener监听类,
* 在onApplicationEvent()方法中执行连接mqtt服务和订阅主题。
**/
@Slf4j
@Component
public class MQTTListener implements ApplicationListener<ContextRefreshedEvent> { private final MQTTConnect server; @Autowired
public MQTTListener(MQTTConnect server) {
this.server = server;
} @Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
try {
// 连接mqtt服务
server.setMqttClient(new Callback(server));
// 订阅主题
server.sub("com/iot/init");
server.sub("com/iot/init1");
server.sub("com/iot/init2");
server.sub("com/iot/init3");
} catch (MqttException e) {
log.error(e.getMessage(), e);
}
}
}

问题分析

由于我们需要在消息监听回调中执行业务逻辑,比如根据消息中的某个字段使用mapper查询数据库。所以在Callback类中用@Autowired引入的项目中的serviceImpl。这里可以看到注入的serviceImpl出现了空指针。

问题原因


在MQTTListener中我们使用了new来创建CallBack这个bean,那么我们在CallBack这个类的示例中注入bean就会失败,出现null。
这里原因可能是new出来的实例对象不由spring管理,所以其内部注入的bean也就失败了。(这里如果说的不对,希望大佬不吝赐教)

解决方法

解决方法就是使用到服务的时候,动态去加载Bean。
  1. 使用applicationContext的getBean()方法在使用的地方动态注入,比如以下的方式。
dynamicRoutingDataSource = applicationContext.getBean(DynamicRoutingDataSource.class);
  1. 在MQTTListener设置回调CallBack类时,使用注入的CallBack类的Bean。

总结

在Spring项目中,尽量统一把bean交给Spring容器管理,少使用new创建实例对象。

参考

记一次Spring项目中使用@Autowired注入bean,使用时报空指针异常的问题
Spring @Autowired注入为null,空指针异常

spring项目使用EMQX,使用@Autowired注入失败报错空指针问题记录的更多相关文章

  1. 【Intellij idea】spring中@Autowired注入失败

    @Autowired注入失败失败的解决办法? 现有的解决的方案是: 打开file-settings或者ctrl+alt+s -> Editor 然后在Inspections 点击搜索栏 输入Sp ...

  2. spring boot开发 @autowired注入失败

    @autowired注入失败 会出现如下错误提示: 2018-05-28 08:39:41.857 INFO 8080 --- [ restartedMain] org.hibernate.Versi ...

  3. 160309、Spring AOP操作action时无法注入,报空指针错误

    今天帮同事看个问题,action注入失败,代码没问题,主要是stuts2权限移交的问题,特此记录一下 Spring AOP操作action时无法注入,报NullPointer异常 当使用Spring ...

  4. Spring AOP操作action时无法注入,报NullPointer异常

    Spring AOP操作action时无法注入,报NullPointer异常当使用Spring AOP对action层进行操作时,会出现注入失败的问题,出现空指针异常.原因是一般struts2+spr ...

  5. idea的service注入mapper报错

    一.问题 idea的java项目中,service类中注入mapper报错 二.解决 方法1 在mapper类上加上  @Repository 注解即可,当然不加也行,程序也不回报错,是idea的误报 ...

  6. RedisCluster的rename机制失败报错,解决又是数据倾斜问题

    需求说明:spring session中的用户session更新是更新key的名字,所以对于key的操作时需要用newkey 替换oldkey value值只允许存在一个,这里用到rename就很合适 ...

  7. sql注入之报错注入and boolean注入

    1.sql注入之报错注入 正常传参,返回页面正常: 加入'  返回页面报错,出现"zhangsan"' 报错注入使用的函数 在这里我们使用 select updatexml(1,c ...

  8. Windows Essentials Movie Maker 安装失败报错 ——问题解决

    Windows Essentials Movie Maker 安装失败报错: (软件包名: wlsetup-all.exe) 查到官方论坛给出了一些回复: https://social.technet ...

  9. laravel 项目表单中有csrf_token,但一直报错419错误 解决redis连接错误:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persi

    laravel 项目表单中有csrf_token,但一直报错419错误,因为项目中使用到Redis缓存,在强制关闭Redis后出现的问题,查询laravel.log文件查找相关问题 安装redis后在 ...

  10. spring JMS在接收消息的时候总是报错

    spring JMS在接收消息的时候总是报错 org.springframework.jms.UncategorizedJmsException: Uncategorized exception oc ...

随机推荐

  1. 深入浅出:Agent如何调用工具——从OpenAI Function Call到CrewAI框架

    深入浅出:Agent如何调用工具--从OpenAI Function Call到CrewAI框架 嗨,大家好!作为一个喜欢折腾AI新技术的算法攻城狮,最近又学习了一些Agent工作流调用工具的文章,学 ...

  2. 斩获“年度突破成果”奖!天翼云构建强大AI算力基础,制胜人工智能新时代

    8月18-19日,2023中国算力大会在宁夏银川举办.在大会"年度突破成果"发布环节,中国电信天翼云<基于异构多云环境下的息壤算力调度应用实践>荣获2023中国算力大会 ...

  3. JMeter中的JavaScript加密实战

    JMeter中的JavaScript加密实战 在性能测试领域,Apache JMeter 作为一款强大的开源工具,广泛应用于模拟多用户并发请求以评估应用程序的性能.然而,在实际的测试场景中,直接传输明 ...

  4. 10GSFP+系列光模块

    10GSFP+双纤系列光模块包括SR.LRM.LR.ER.ZR模块,它们的接口类型都是LC双工,且符合IEEE802.3ae.SFF-8472和SFF-8431标准,以下是这几种光模块的具体详情. 1 ...

  5. mac安装spark

    一.基础信息 spark版本:spark-3.1.3-bin-hadoop3.2 hadoop版本:hadoop-3.2.1 scala版本:scala-2.11.12  建议3.12版本 下载地址: ...

  6. Hetao P1307 树的剖分 题解 [ 蓝 ] [ 树形 dp ] [ 贪心 ]

    树的剖分:很厉害的性质题,代码也很好写.运用到了奇偶性拼凑答案的 trick. 观察 首先发现一个很重要的条件:一个点的点权只可能是 \(0,1,2\). 这个条件开始我们可能无法用上,于是先想最后的 ...

  7. 如何配置 maven 编译插件的 JDK 版本

    普通maven项目配置编译器版本 参考maven官方文档 Setting the -source and -target of the Java Compiler maven有2种方法设置编译JDK版 ...

  8. Redis 持久化原理分析和使用建议

    作者:来自 vivo 互联网存储团队-  Qiu Xu 本文主要介绍了 Redis 提供的三大持久化机制,即 AOF 日志.RDB 快照以及混合持久化机制. 一.Redis 为什么需要进行持久化 Re ...

  9. 开源一款I2C电机驱动扩展板-FreakStudio多米诺系列

    总线直流电机扩展板 原文链接: FreakStudio的博客 摘要 设计了一个I2C电机驱动板,通过I2C接口控制多个电机的转速和方向,支持刹车和减速功能.可连接16个扩展板,具有PWM输出.过流过热 ...

  10. KUKA库卡机器人维修碰撞、电源、网络故障

    在进行库卡机器人的维修作业时,我们通常要遵循一系列经过精心设计和标准化的操作流程与步骤,以确保维修工作的切实有效以及机器人能够在安全的状态下运行.   针对库卡机器人维修中的故障原因分析,可以从以下几 ...