SpringBoot - 整合WebSocket时@ServerEndpoint修饰的类属性注入为null问题

news2024/11/15 13:42:03

SpringBoot - 整合WebSocket时@ServerEndpoint修饰的类属性注入为null问题

  • 前言
  • 一. 问题复现
    • 1.1 原因分析
  • 二. 问题解决

前言

最近在做一个直播弹幕系统,前期准备先用WebSocket来试试水。我们都知道,使用WebSocket只需要给对应的类加上注解@ServerEndpoint即可。这个类中我还引用了一个MQ的服务类,结果调用的时候发现NPE。因此写下本篇文章做个记录。
在这里插入图片描述

一. 问题复现

1.我们建立一个WebSocket链接,后端感知到了链接建立(@OnOpen注解)之后,通过originMessageSender发送一条消息出去。
在这里插入图片描述
相关代码如下:
在这里插入图片描述

但是代码跑到这里却发现originMessageSender这个对象为null,那么这段代码执行的时候自然而然的就是NPE异常了。
在这里插入图片描述
如图:
在这里插入图片描述

为什么会发生这种情况呢?我们来分析下。

1.1 原因分析

首先我们来从@AutowiredBean的属性注入角度来看。

  1. 容器启动的时候,会将每个单例Bean加载到容器当中。
  2. 单例Bean的加载有三个步骤。实例化、依赖注入、初始化。而@Autowired的作用就体现于依赖注入当中。
  3. 我们BulletScreenService类中,通过@AutowiredOriginMessageSender进行自动装配。其实他是成功的,假设我们这时候装配的对象是sender1

接着我们再来从WebSocket的角度来看:

  1. 我们每建立一个WebSocket链接,都会产生一个新的对象,也就是被@ServerEndpoint修饰的对象。
  2. 也就是WebSocket是一个多例的对象而非单例。 也就是说,当建立链接之后创建的BulletScreenService实例对象和容器启动的时候,加载到容器当中的BulletScreenServiceBean已经不是一个东西了。
  3. 那么为什么通过@Autowired注入的对象是null呢?因为@Autowired注解注入对象是在启动的时候就把对象注入,而不是在使用A对象时才把A需要的B对象注入到A中的。

因此我们每建立一个WebSocket链接,按照上面的写法,我们是无法注入OriginMessageSender的。

二. 问题解决

既然给对象注入属性不可行,那么我们换位思考,给类属性注入不就好了嘛?修改如下。

原本代码:

@Autowired
private OriginMessageSender originMessageSender;

修改后代码:

private static OriginMessageSender originMessageSender;
@Autowired
private void setOriginMessageSender(OriginMessageSender originMessageSender) {
    BulletScreenService.originMessageSender = originMessageSender;
}

那么在容器启动的时候,就会加载这段代码,然后将originMessageSender实例赋值给静态变量。(我们知道静态变量属于类,而不是实例对象)
在这里插入图片描述
那么同样的,当我们客户端建立起和服务端的WebSocket链接,发送消息的时候:这里就不再是Null了。
在这里插入图片描述

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

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

相关文章

Linux之定时任务--crontab命令解析学习

Corntab定时任务学习 一、crond服务 在学习crontab,命令之前,我觉得有必要学习了解一下crond服务,因为要在linux系统下使用crontab命令需要crond的支持。Crond是Linux下要用来周期执行某种任务或者等待处理某些事件的一个守护进程。和Windo…

项目——员工管理系统

开发环境:vmware ubuntu18.04 实现功能:基本功能包括管理者和普通员工用户的登录,管理者拥有操作所有员工信息的最高权限,可以进行增删改 查等操作,普通用户仅拥有查看、修改个人部分信息的权限 具体功能详解&…

python 学习笔记

解决执行python"ImportError: No module named requests"问题 #切换到python的安装目录执行如下命令 D:\Python27>pip install requestsImportError: No module named bs4错误解决方法 运行脚本时提示ImportError: No module named bs4错误,原因&…

[附源码]计算机毕业设计基于vue的软件谷公共信息平台Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Python——有限状态机

有限状态机(Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。FSM是一种算法思想,简单而言,有限状态机由一组状态…

【Lilishop商城】No3-5.模块详细设计,商品模块-1(商品分类、品牌管理、规格管理、参数、计量单位、店铺分类)的详细设计

仅涉及后端,全部目录看顶部专栏,代码、文档、接口路径在: 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接口类、业务类,具体的结合源代码…

人脸特征点检测入门

基础 人脸特征点可以用来做脸型、眼睛形状、鼻子形状等分析,从而对人脸的特定位置进行修饰加工,实现人脸的特效美颜。人脸识别等算法可以通过对人脸的姿态进行对齐从而提高模型的精度。 68点标注是现今最通用的一种标注方案,早期在1999年的…

Effective C++条款30:透彻了解inlining的里里外外(Understand the ins and outs of inlining)

Effective C条款30:透彻了解inlining的里里外外(Understand the ins and outs of inlining)条款30:透彻了解inlining的里里外外1、inline函数的优缺点2、隐式内联和显式内联2.1 隐式内联2.2 显式内联3、函数模板必须inline么&…

自动驾驶之3D点云聚类算法调研

1. 方法 总共分为4类 基于欧式距离的聚类Supervoxel 聚类深度(Depth) 聚类Scanline Run 聚类 1.1 基于欧氏距离的聚类 思路: 在点云上构造kd-tree, 然后在某个半径阈值(例如0.5m), 则分割为一个实例。 相似算法: RBNN (radially bounded nearest neighbor graph), 2008. …

在 Ubuntu 上安装 Discourse 开发环境

本指南只针对 Discourse 开发环境的配置,如果你需要在生产环境中安装 Discourse ,请访问页面:Install Discourse in production with the official, supported instructions - sysadmin - Discourse Meta 中的内容。 有关开发环境的设置英文原…

[Java EE初阶] 进程调度的基本过程

纪念Java EE初阶开篇文章,不放弃,不摆烂,踏平所有障碍吧!少年!奥利给!(操作系统这方面的所有文章均不作为操作系统的专业课知识学习) 文章目录1. 进程的概念2. PCB --- 进程控制块3. 并发与并行4. 进程调度的相关属性5. 内存管理总结1. 进程的概念 进程,就是跑起来的程序,我们…

【学习笔记】《Python深度学习》第七章:高级的深度学习最佳实践

文章目录1 Keras 函数式 API1.1 函数式 API 简介1.2 多输入模型1.3 多输出模型1.4 层组成的有向无环图1.5 共享层权重1.6 将模型作为层2 使用 Keras 回调函数 和 TensorBoard 检查并监控深度学习模型2.1 训练过程中将回调函数作用于模型2.2 TensorBoard 简介:Tensor…

【Lilishop商城】No3-4.模块详细设计,店铺店员(店铺店员、店铺部门、店铺角色)的详细设计

仅涉及后端,全部目录看顶部专栏,代码、文档、接口路径在: 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接口类、业务类,具体的结合源代码…

exfat文件系统

DBR: DBR偏移量 字段长度(字节) 说明 0x40 - 0x47 8 分区的起始扇区号(隐藏扇区数) 0x48 - 0x4F 8 分区总扇区数 0x50 - 0x53 4 FAT表起始扇区号(从DBR到FAT表的扇区个数) 0x54 - 0x57 4…

【Redis】持久化操作

一、RDB(Redis Database) 1、持久化 redis一般是将数据写到内存中,但也可以将数据写到磁盘中,这个过程称之为持久化 2、什么是RDB 在指定的时间间隔内将内存中的数据集快照写入磁盘中 3、RDB是如何执行备份操作的 redis会单独创建(fork)一个子进程进行…

FPGA 20个例程篇:18.SD卡存放音频WAV播放(下)

第七章 实战项目提升,完善简历 18.SD卡存放音频WAV播放(下) 进一步地我们再结合图1的示意图来分析wav_play模块的时序逻辑设计,大家可以清楚地看到WM8731在Right justified和主从时钟模式下,是先发左声道后发右声道数…

【LeetCode】专题一 二叉树层序遍历

二叉树层序遍历 在本文中,我将会选取LeetCode上二叉树层序遍历的多道例题,并给出解答,通过多道题我们就可以发现,二叉树的层序遍历并不复杂,并且有着共通点。 102. 二叉树的层序遍历 给你二叉树的根节点 root &…

【Labivew】简易计算器

🚩write in front🚩 🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5&#xff5…

Secure CRT远程连接很快断线问题

问题描述 我们使用Secure CRT连接远程主机时可能会遇到几分钟没操作就无法操作了,需要断开重新连接,非常的麻烦,假如客户端或者服务端能够在快要超时的时候给对方发送一个心跳,得到对方响应就重置下超时时间,这样就能…

arm架构 --- 中断

ARM的异常 终止程序的正常执行过程而不得不去完成的一些特殊工作 中断是异常的一种,包括外部硬件产生的异常和芯片内部硬件产生的内部中断。 ARM有七种处理器模式,其中用户模式和系统模式之外的5钟处理器模式叫做异常模式,用户模式之外的6…