spring boot打造的websocket服务器端中类自动实例化问题

栏目: Html5 · 发布时间: 5年前

内容简介:版权声明:本文为博主原屙文章,喜欢你就担走。 https://blog.csdn.net/leftfist/article/details/89217214

版权声明:本文为博主原屙文章,喜欢你就担走。 https://blog.csdn.net/leftfist/article/details/89217214

唉,真拗口啊这标题,也不知道说的对不对,好像很不专业的说法?大致是这么个意思吧。

总所周知,spring boot最喜欢最擅长干的事情就是标注。多复杂的事情,只要加个标注就好了。1个不够,就加2个。没有标注解决不了的问题。

比如说,类的实例化,只需加个 @Autowired 就好了:

@Autowired
SocketService skService;

但是!在websocket 服务器端代码中,这种实例会失效,根本没有构造实例,skService为null。

为什么会这样呢?

原因据说是spring 为单例模式,而websocket是多对象,每个会话会创建一个websocket对象。导致除了第一个websocket,其他的都不能注入实例。

本质原因:spring管理的都是单例(singleton),和 websocket (多对象)相冲突。

原文: https://blog.csdn.net/m0_37202351/article/details/86255132

我寻寻觅觅,找到的答案都说是要在每个具体的上下文里自己构造实例。试验之后,果真如此,代码如下:

websocket服务端

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/ws")
@Component
public class CaptureSocket {
    private final static Logger LOGGER = LoggerFactory.getLogger(CaptureSocket.class);

    private static CopyOnWriteArraySet<CaptureSocket> set = new CopyOnWriteArraySet<>();
    private Session session;
	
    //关键代码,设置一个静态上下文属性appcontext
	private static ApplicationContext appcontext;
    public static void setAppcontext(ApplicationContext appcontext) {
        CaptureSocket.appcontext = appcontext;
    }
	public static ApplicationContext getAppcontext() {
        return appcontext;
    }

    @OnMessage
    public void onMessage(String message,Session session){
        LOGGER.info("来自客户端消息:" + message);
		//手动构造实例
		//这个构造实例,要放在事件里进行,如果放在代码开头,极有可能失败,可能是还没来得及拿到这个上下文对象?
		SocketService skService = appcontext.getBean(SocketServiceImpl.class);
    }
	@OnOpen
    public void onOpen(Session session) throws IOException,InterruptedException {
        this.session=session;
        set.add(this);
        LOGGER.info("新连接来自:" + session.getRequestURI().getHost());
    }
    @OnClose
    public void onClose(){
        set.remove(this);
        LOGGER.info("连接关闭:" + this.session.getRequestURI().getHost());
    }
    @OnError
    public void onError(Session session,Throwable err){
        LOGGER.info(err.getMessage());
        err.printStackTrace();
    }
}

在主程序入口里,将上下文对象保存下来,保存到websocket代码设置的静态属性appcontext里。如此,即可用该上下文对象来构造实例矣。

@SpringBootApplication
@EnableAsync
public class OptcFfmpegApplication {
    
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(OptcFfmpegApplication.class, args);
        CaptureSocket.setAppcontext(context);
    }
}

但是要注意,这个构造实例,要放在事件里进行,如果放在代码开头,极有可能失败,可能是还没来得及拿到这个上下文对象?


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

第三次浪潮

第三次浪潮

[美]阿尔文·托夫勒 / 黄明坚 / 中信出版集团 / 2018-7 / 79.00元

《第三次浪潮》是美国著名未来学家阿尔文•托夫勒的代表作之一。1980年出版之际,随即引起全球热评,堪称中国改革开放的指南。本书阐述了由科学技术发展引起的社会各方面的变化与趋势。托夫勒认为,人类迄今为止已经经历了两次浪潮文明的洗礼:第一次是农业革命,人类就此从原始渔猎时代进入以农业为基础的文明社会,并历经千年,直到工业革命的到来。随后,人类社会历时300年摧毁了落后的第一次浪潮文明,并在“二战”后1......一起来看看 《第三次浪潮》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具