当前位置: 代码网 > it编程>编程语言>Java > Springboot使用Websocket的时候调取IOC管理的Bean报空指针异常问题

Springboot使用Websocket的时候调取IOC管理的Bean报空指针异常问题

2025年05月15日 • Java •我要评论
问题这个问题主要是因为websocket的工作方式导致的,下面是详细解决方案解决websocket 端点类通常不受 spring ioc 管理的原因在于它们是由 websocket 容器(例如,tom

问题

这个问题主要是因为websocket的工作方式导致的,下面是详细解决方案

解决

websocket 端点类通常不受 spring ioc 管理的原因在于它们是由 websocket 容器(例如,tomcat、jetty 等)而不是 spring 容器管理的。

websocket 规范(jsr 356)定义了 websocket 端点的生命周期和管理方式,这通常与 spring 的生命周期和依赖注入机制不同。

以下是一些具体原因和解决方法:

原因

不同的生命周期管理:

  • websocket 端点的创建和管理是由 web 容器(如 tomcat、jetty 等)负责的,而不是由 spring 容器负责。
  • 这意味着 websocket 端点类的实例化和生命周期管理不在 spring 的控制范围内。

注入机制不同:

  • spring 的依赖注入机制依赖于 spring 容器管理的 bean,但 websocket 端点类实例化时,web 容器并不知道如何进行依赖注入。

解决方法

方法一:使用 spring boot 和 @configuration 配置

在 spring boot 项目中,可以通过配置类和自定义 websocket 处理器来管理 websocket 连接,这样可以使用 spring 容器管理的 bean。

创建 websocket 配置类:

import org.springframework.context.annotation.configuration;
import org.springframework.web.socket.config.annotation.enablewebsocket;
import org.springframework.web.socket.config.annotation.websocketconfigurer;
import org.springframework.web.socket.config.annotation.websockethandlerregistry;

@configuration
@enablewebsocket
public class websocketconfig implements websocketconfigurer {

    private final mywebsockethandler mywebsockethandler;

    public websocketconfig(mywebsockethandler mywebsockethandler) {
        this.mywebsockethandler = mywebsockethandler;
    }

    @override
    public void registerwebsockethandlers(websockethandlerregistry registry) {
        registry.addhandler(mywebsockethandler, "/websocket").setallowedorigins("*");
    }
}

创建 websocket 处理器类:

import org.springframework.web.socket.textmessage;
import org.springframework.web.socket.websocketsession;
import org.springframework.web.socket.handler.textwebsockethandler;
import org.springframework.stereotype.component;

@component
public class mywebsockethandler extends textwebsockethandler {

    private final someservice someservice;

    public mywebsockethandler(someservice someservice) {
        this.someservice = someservice;
    }

    @override
    public void handletextmessage(websocketsession session, textmessage message) throws exception {
        string payload = message.getpayload();
        system.out.println("消息为:" + payload);
        someservice.dosomething();  // 使用 spring bean
        session.sendmessage(new textmessage("servet 发送:" + payload));
    }
}

方法二:使用自定义 springconfigurator

创建自定义的 springconfigurator:

import javax.websocket.server.serverendpointconfig;
import org.springframework.web.context.contextloader;
import org.springframework.web.context.webapplicationcontext;

public class springconfigurator extends serverendpointconfig.configurator {

    @override
    public <t> t getendpointinstance(class<t> clazz) throws instantiationexception {
        webapplicationcontext context = contextloader.getcurrentwebapplicationcontext();
        if (context == null) {
            throw new instantiationexception("unable to get spring context.");
        }
        return context.getautowirecapablebeanfactory().createbean(clazz);
    }
}

在 @serverendpoint 注解中指定 configurator:

import javax.websocket.onmessage;
import javax.websocket.server.serverendpoint;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.component;

@serverendpoint(value = "/websocket", configurator = springconfigurator.class)
@component
public class mywebsocket {

    @autowired
    private someservice someservice;  // 由 spring 管理的 bean

    @onmessage
    public string onmsg(string text) throws ioexception {
        system.out.println("消息为:" + text);
        someservice.dosomething();  // 使用 spring bean
        return "servet 发送:" + text;
    }
}

方法三:手动获取 spring bean

创建 applicationcontextprovider 类:

import org.springframework.context.applicationcontext;
import org.springframework.context.applicationcontextaware;
import org.springframework.stereotype.component;

@component
public class applicationcontextprovider implements applicationcontextaware {

    private static applicationcontext context;

    @override
    public void setapplicationcontext(applicationcontext applicationcontext) {
        context = applicationcontext;
    }

    public static applicationcontext getapplicationcontext() {
        return context;
    }
}

在 websocket 类中使用 applicationcontextprovider 获取 bean:

import javax.websocket.onmessage;
import javax.websocket.server.serverendpoint;
import org.springframework.stereotype.component;

@serverendpoint(value = "/websocket")
@component
public class mywebsocket {

    private someservice someservice;

    public mywebsocket() {
        this.someservice = applicationcontextprovider.getapplicationcontext().getbean(someservice.class);
    }

    @onmessage
    public string onmsg(string text) throws ioexception {
        system.out.println("消息为:" + text);
        someservice.dosomething();  // 使用 spring bean
        return "servet 发送:" + text;
    }
}

通过这些方法,你可以确保 websocket 端点类能够正确地访问由 spring ioc 管理的 bean,从而避免空指针异常。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

赞 (0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com