avatar

Spring中的小知识点

Spring中的websocket

在Spring中如果没有特殊指明,一般都是以单例生成的,而webSocket的机制是每个连接都会创建一个对象,用来维护连接。那么问题来了,在Spring中是怎么处理这个关系的,如果没有特殊声明,Spring中的WebSocket对象是单例还是原型呢。
这个问题是由我一个同事问我的,他问我他利用@Component注解向Spring中注册了一个WebSocket对象,如果说Spring中是单例模式,每次连接WebSocket的时候创建的Session应该会把之前的Session给覆盖掉,也就是说应该每次只有一个用户能连接进来,但是现在的现象是不管多少用户不仅Seesion不会覆盖,而且连接也不会断,每个都好好的,完全不会出现预想的情况,难道是Spring里面的webSocket不是单例?采用的是原型模式?
对于我这种菜鸡来说,我只会用,没有想那么多,但是既然人家问了那我就应该去研究一下。我们从使用入手看一下webScoket是怎么在Spring中存在的

Spriung-webSocket使用方式

@ServerEndpoint(value = "/webSocketTest")
@Component
public class webSocketTest {
//TODO:做一些事请
}
  • @Component是将webSocketTest注册到Spirng中。如果不加Scope注解,默认就是单例模式,
  • @ServerEndpoint是设置一个ws路由,可以理解为一个controller,也就是webSocketTest为webSocket连接类
    这样想来,应该出现的情况是,每次有连接我就会覆盖掉session,只会维持一个ws连接,首先我们做一下实验

实验一

我们在onMessage方法中打印这么一系列的东西

@OnMessage
public void onMessage(String message, Session session) throws IOException {
System.out.println("session的id为:"+this.session.getId());
System.out.println("webSocketTest对象的hashcode:"+this.hashCode());
System.out.println(message);
this.session.getBasicRemote().sendText("消息为:"+message);
}

然后我维持两个连接,webSocket测试网站,然后分别发消息进行测试,输出如下

session的id为:0
webSocketTest对象的hashcode:486975051
1
session的id为:1
webSocketTest对象的hashcode:718234295
1

也就是说webSocket会为每次连接都创建一个webSocketTest,每个webSocketTest又有自己的Session。下面进行第二个实验,我们从Spring中取在Spring中的webSocketTest对象

实验二

我们增加打印的内容

@OnMessage
public void onMessage(String message, Session session) throws IOException {
System.out.println("session的id为:"+this.session.getId());
System.out.println("webSocketTest对象的hashcode:"+this.hashCode());
SystemMonitorWebSocket bean = SpringContext.APPLICATION_CONTEXT.getBean(webSocketTest.class);
System.out.println("Spring容器中的webSocketTest:"+bean.hashCode());
System.out.println(message);
this.session.getBasicRemote().sendText("消息为:"+message);
}

输出为:

session的id为:0
webSocketTest对象的hashcode:486975051
Spring容器中的webSocketTest:267518494
1
session的id为:1
webSocketTest对象的hashcode:718234295
Spring容器中的webSocketTest:267518494
1

这里可以看出,在Spring容器中的webSocketTest类每次打印的hashcode都是一样的,也就是说在Spring容器中的webSocketTest是单例的,但是由于webSocket的机制,每次请求都会生成一个对象来维护连接。

总结

  • webSocket类在Spring中的实例是单例的只有一个
  • webSocket机制每次建立连接都会创建一个实例来维护连接
  • @Component的作用是将webSocket类加入到Spring容器中,让Spring容器识别@ServerEndpoint然后利用Spring中的webSocket组件进行WebSocket管理
文章作者: zenshin
文章链接: https://zlh.giserhub.com/2020/11/23/spring/things/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 zenshin's blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论