在 WebSocket 中使用 @Autowired 时遇到空指针异常

背景:在websocket在有新的连接加入进来时,调用servier中的服务,使用 @Autowired 注入的 Bean 竟然是 null!这并非 Spring 的 Bug,而是对 WebSocket 生命周期管理理解不足导致的。

了解这个问题,我们需要区分两个关键概念:

  • Spring 容器: 负责管理 Bean 的生命周期,包括实例化、依赖注入和销毁。
  • WebSocket 容器: 负责管理 WebSocket 端点的生命周期,例如建立连接、接收消息和关闭连接。

默认情况下,WebSocket 容器负责创建 @ServerEndpoint 注解的类的实例,并且不会使用 Spring 的依赖注入机制。 这意味着即使你使用了 @Component 注解,Spring 容器也不会自动将 Bean 注入到 WebSocket 端点类中。

一些文章将此问题归咎于 Spring Bean 的单例特性与 WebSocket 端点类的多例特性之间的冲突。这种说法并不准确。 Spring 的依赖注入机制并不限制单例 Bean 注入到多例 Bean 中。

问题的根源在于:Spring 容器根本没有参与 WebSocket 端点类的实例化过程,因此依赖注入也就无从谈起。

可以使用上下文类来得到:

@Component
public class SpringContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHolder.context = applicationContext;
    }

    public static <T> T getBean(Class<T> clazz) {
        return context.getBean(clazz);
    }
}

在使用的时候,get需要的

 SpringContextHolder.getBean(MetalDefectDetectionService.class);
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值