WebSocket 中使用 @Autowired 注入对应为null的解决方案

 更新时间:2024年10月22日 09:30:59   作者:_江屿_  
SpringBoot集成WebSocket时,会遇到service对象为null的情况,原因是Spring默认为单例模式与WebSocket的多对象模式相冲突,当客户端与服务器端建立连接时,会创建新的WebSocket对象,本文给大家介绍WebSocket 中使用 @Autowired 注入对应为null的问题,感兴趣的朋友一起看看吧

代码示例

@Component
public class WebSocketHandlerMessage implements WebSocketHandler {
    @Autowired
    private BarrageMessageService barrageMessageService;
}

结果显示

SpringBoot项目集成 webSocket,当客户端与服务器端建立连接的时候,发现  barrageMessageService 对象并未注入而是为 null。

产生原因:spring管理的都是单例(singleton),和 websocket (多对象)相冲突。
详细解释:项目启动时初始化,会初始化 websocket (非用户连接的),spring 同时会为其注入 service,该对象的 service 不是 null,被成功注入。但是,由于 spring 默认管理的是单例,所以只会注入一次 service。当客户端与服务器端进行连接时,服务器端又会创建一个新的 websocket 对象,这时问题出现了:spring 管理的都是单例,不会给第二个 websocket 对象注入 service,所以导致只要是用户连接创建的 websocket 对象,都不能再注入了。

像 controller 里面有 service, service 里面有 dao。因为 controller,service ,dao 都有是单例,所以注入时不会报 null。但是 websocket 不是单例,所以使用spring注入一次后,后面的对象就不会再注入了,会报NullException。

解决方法:

方案一:使用静态,让 service 属于类,然后给类的 service 注入。

@Component
public class WebSocketHandlerMessage implements WebSocketHandler {
    /**
     *  这里使用静态,让 service 属于类
     */
    private static BarrageMessageService barrageMessageService;
    /**
     *  注入的时候,给类的 service 注入
     */
    @Autowired
    public void setBarrageMessageService(BarrageMessageService barrageMessageService) {
        WebSocketHandlerMessage.barrageMessageService = barrageMessageService;
    }
}

方案二:在新建立连接的时候重新从Spring 容器中获取 BarrageMessageService 对象,这样就可以正常使用了。

@Component
public class WebSocketHandlerMessage implements WebSocketHandler {
    /**
     * 获取 barrageMessageService 对象方法
     *
     * @return
     */
    public BarrageMessageService getMessageService() {
        return SpringContext.getBean(BarrageMessageService.class);
    }
    /**
     * 获取 stringRedisTemplate 对象方法
     *
     * @return
     */
    public StringRedisTemplate getStringRedisTemplate() {
        return SpringContext.getBean(StringRedisTemplate.class);
    }
}

SpringContext 工具类方法: 

/**
 * @Description: SpringContext  获取 Spring 上下文信息
 * @Author: mingtian
 * @CreateDate: 2020/6/8 14:59
 * @Version: 1.0
 */
@Component
public class SpringContext implements ApplicationContextAware {
    /**
     * 打印日志
     */
    private Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 获取上下文对象
     */
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContext.applicationContext = applicationContext;
        logger.info("set applicationContext");
    }
    /**
     * 获取 applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    /**
     * 通过 name 获取 bean 对象
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
    /**
     * 通过 class 获取 bean 对象
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
    /**
     * 通过 name,clazz  获取指定的 bean 对象
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

以上二种方案都可以解决,webSocket 中 service 注入为 null 的问题。

到此这篇关于WebSocket 中使用 @Autowired 注入对应为null的文章就介绍到这了,更多相关WebSocket @Autowired 注入为null内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java生成json数据示例

    java生成json数据示例

    这篇文章主要介绍了java生成json数据示例,需要的朋友可以参考下
    2014-04-04
  • @Validated验证List集合的方法示例

    @Validated验证List集合的方法示例

    这篇文章主要介绍了@Validated验证List集合的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • MyBatis-Plus逆向工程——Generator的使用

    MyBatis-Plus逆向工程——Generator的使用

    这篇文章主要介绍了MyBatis-Plus逆向工程——Generator的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java项目中防止SQL注入的四种方法推荐

    Java项目中防止SQL注入的四种方法推荐

    sql注入是web开发中最常见的一种安全漏洞,这篇文章为大家整理了四种Java项目中防止SQL注入的方法,有需要的小伙伴可以参考一下
    2025-03-03
  • 深入聊一聊springboot项目全局异常处理那些事儿

    深入聊一聊springboot项目全局异常处理那些事儿

    最近在做项目时需要对异常进行全局统一处理,所以下面这篇文章主要给大家介绍了关于springboot项目全局异常处理那些事儿,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • SpringBoot自定义MessageConvert详细讲解

    SpringBoot自定义MessageConvert详细讲解

    正在学习SpringBoot,在自定义MessageConverter时发现:为同一个返回值类型配置多个MessageConverter时,可能会发生响应数据格式错误,或406异常(客户端无法接收相应数据)。在此记录一下解决问题以及追踪源码的过程
    2023-01-01
  • springboot 文件上传大小配置的方法

    springboot 文件上传大小配置的方法

    本篇文章主要介绍了springboot 文件上传大小配置的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Java的类型擦除式泛型详解

    Java的类型擦除式泛型详解

    Java语言中的泛型只存在于程序源码之中,在编译后的字节码文件里,则全部泛型都会被替换为原来的原始类型(Raw Type),并且会在相应的地方插入强制转型的代码。这篇文章主要介绍了Java的类型擦除式泛型,需要的朋友可以参考下
    2021-08-08
  • MyBatis 如何配置多个别名 typeAliasesPackage

    MyBatis 如何配置多个别名 typeAliasesPackage

    这篇文章主要介绍了MyBatis 如何配置多个别名 typeAliasesPackage,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Sonar编译问题对应:File [...] can''t be indexed twice.

    Sonar编译问题对应:File [...] can''t be indexed twice.

    今天小编就为大家分享一篇关于Sonar编译问题对应:File [...] can't be indexed twice.,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论