SpringBoot使用@ServerEndpoint無法依賴注入問題解決(WebSocket)

如上兩圖所示,在WebSocket中我想使用Redis。把自己編寫的RedisUtil使用@Autowired自動注入到當前類。

在運行時,出現異常:java.lang.NullPointException (上面第二張圖的代碼)

A.可能原因:自己編寫的RedisUtil沒有放到spring容器中(導致沒有實例化)。經過測試,排除此原因。(測試過程略)

B.解決思路:WebSocket是線程安全的,有用戶連接時就會創建一個新的端點實例,一個端點只能保證一個線程調用。總結就是,WebSocket是多對象的。不管單獨使用也好,結合spring也好,或者結合SpringBoot也罷,他都是多對象的。

C.問題原因:WebSocket是多對象的,使用的spring卻是單例模式。這兩者剛好衝突。@Autowired註解注入對象是在啓動的時候就把對象注入,而不是在使用A對象時才把A需要的B對象注入到A中。而WebSocket在剛剛有說到,有連接時才實例化對象,而且有多個連接就有多個對象。由此得知,RedisUtil根本就沒有注入到WebSocket當中。

D.解決問題:解決的方式有兩種。1.讓Redis屬於WebSocketServer這個類   2.在運行時,動態的從spring容器中取出RedisUtil。

第一種:

 private static RedisUtil redisUtil;
 
    @Autowired
    public static void setRedisUtil(RedisUtil redisUtil) {
        WebSocketServer.redisUtil = redisUtil;
    }
第二種:         

編寫從容器中取對象的工具類

@Component
public class SpringUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtil.applicationContext = applicationContext;
    }
 
    public ApplicationContext getApplicationContext(){
        return applicationContext;
    }
 
    public static Object getBean(String beanName){
        return applicationContext.getBean(beanName);
    }
 
    public static <T> T getBean(Class<T> clazz){
        return (T)applicationContext.getBean(clazz);
    }
}
 然後再WebSocket中

private RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
啊~行了行了,就到這了。

最後再嗶嗶一句,原理枯燥噁心。但解決問題的時候真香!~
————————————————
版權聲明:本文爲CSDN博主「王百逸」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Programmer__Wang/article/details/88538993

發佈了515 篇原創文章 · 獲贊 142 · 訪問量 100萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章