问题:
为什么使用了@Component注解,还可以用this来代表不同的连接?
@Component不是单例模式吗?this不是都指向同一个地址吗?这样写真的可以吗?
上@ServerEndpoint代码:
来,我们直接找chatgpt问问这个问题的答案,说的模棱两可的,上图:
上图,感觉说的好像对,好像又不对,思来想去还是想不通,最终决定在源码debug一探究竟
经过一番摸索以后,定位到了源码中的关键三步,如下进行图文分析:
模拟一个ws连接,然后打断点
第一步,ws连接进入onopen事件断点,如图可以看到我们的endpointClass已经被找到了,就是我们对应的ScreenWebSocketServer
第二步,对于这个源码的onOpen方法进行简要分析查看,如下图:
我们点进去这个pojo = sec.getConfigurator().getEndpointInstance(sec.getEndpointClass());方法查看,如图:
下面就是最关键的代码调用替换,也就是我们写的代码是在这一步与源码关联上的
,如图分析:
1)先记录一下调用之前,这个pojo的内存地址
2)进入源码的doOnOpen方法,查看并分析其主要代码结构,如下图:
3)下面就是关键的一步,源码中进行调用springboot容器中使用了@ServerEndPoint类的onopen方法,如果有直接调用,我们的断点也是直接跳到了我们的业务代码中
methodMapping.getOnOpen().invoke(pojo,
methodMapping.getOnOpenArgs(
pathParameters, session, config));
为了简要说明,我们将项目中使用了@ServerEndPoint的类统称为websocketEndPoint类(只是为了叙述方便)。
综上所述,@ServerEndPoint注解的类中代码的this指向的就是ws连接的
websocketEndPoint类的全新实例
,即每次ws连接就是一个新的websocketEndPoint类实例,所以this每次都指向这个新实例。
所以,这里的
this与@Component的单例模式无关
,可以理解@ServerEndPoint和@component同时使用时,@Component的作用就只是将这个类对应的代码托管给springboot集成的websocket,它并不是单例的,所以可以在@OnOpen,@OnClose中使用this来区分每次不同的连接