背景:在websocket在有新的連接加入進來時,調用servier中的服務,使用?@Autowired
?注入的 Bean 竟然是?null
!這并非 Spring 的 Bug,而是對 WebSocket 生命周期管理理解不足導致的。
了解這個問題,我們需要區分兩個關鍵概念:
- Spring 容器:?負責管理 Bean 的生命周期,包括實例化、依賴注入和銷毀。
- WebSocket 容器:?負責管理 WebSocket 端點的生命周期,例如建立連接、接收消息和關閉連接。
默認情況下,WebSocket 容器負責創建?@ServerEndpoint
?注解的類的實例,并且不會使用 Spring 的依賴注入機制。?這意味著即使你使用了?@Component
?注解,Spring 容器也不會自動將 Bean 注入到 WebSocket 端點類中。
一些文章將此問題歸咎于 Spring Bean 的單例特性與 WebSocket 端點類的多例特性之間的沖突。這種說法并不準確。?Spring 的依賴注入機制并不限制單例 Bean 注入到多例 Bean 中。
問題的根源在于:Spring 容器根本沒有參與 WebSocket 端點類的實例化過程,因此依賴注入也就無從談起。
可以使用上下文類來得到:
@Component public class SpringContextHolder implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {SpringContextHolder.context = applicationContext;}public static <T> T getBean(Class<T> clazz) {return context.getBean(clazz);} }
在使用的時候,get需要的
SpringContextHolder.getBean(MetalDefectDetectionService.class);