当前位置: 代码网 > 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-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com