如上兩圖所示,在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