WebSocket 中使用 @Autowired 注入對應(yīng)為null的解決方案
代碼示例:
@Component
public class WebSocketHandlerMessage implements WebSocketHandler {
@Autowired
private BarrageMessageService barrageMessageService;
}結(jié)果顯示:
SpringBoot項目集成 webSocket,當(dāng)客戶端與服務(wù)器端建立連接的時候,發(fā)現(xiàn) barrageMessageService 對象并未注入而是為 null。
產(chǎn)生原因:spring管理的都是單例(singleton),和 websocket (多對象)相沖突。
詳細解釋:項目啟動時初始化,會初始化 websocket (非用戶連接的),spring 同時會為其注入 service,該對象的 service 不是 null,被成功注入。但是,由于 spring 默認管理的是單例,所以只會注入一次 service。當(dāng)客戶端與服務(wù)器端進行連接時,服務(wù)器端又會創(chuàng)建一個新的 websocket 對象,這時問題出現(xiàn)了:spring 管理的都是單例,不會給第二個 websocket 對象注入 service,所以導(dǎo)致只要是用戶連接創(chuàng)建的 websocket 對象,都不能再注入了。
像 controller 里面有 service, service 里面有 dao。因為 controller,service ,dao 都有是單例,所以注入時不會報 null。但是 websocket 不是單例,所以使用spring注入一次后,后面的對象就不會再注入了,會報NullException。
解決方法:
方案一:使用靜態(tài),讓 service 屬于類,然后給類的 service 注入。
@Component
public class WebSocketHandlerMessage implements WebSocketHandler {
/**
* 這里使用靜態(tài),讓 service 屬于類
*/
private static BarrageMessageService barrageMessageService;
/**
* 注入的時候,給類的 service 注入
*/
@Autowired
public void setBarrageMessageService(BarrageMessageService barrageMessageService) {
WebSocketHandlerMessage.barrageMessageService = barrageMessageService;
}
}方案二:在新建立連接的時候重新從Spring 容器中獲取 BarrageMessageService 對象,這樣就可以正常使用了。
@Component
public class WebSocketHandlerMessage implements WebSocketHandler {
/**
* 獲取 barrageMessageService 對象方法
*
* @return
*/
public BarrageMessageService getMessageService() {
return SpringContext.getBean(BarrageMessageService.class);
}
/**
* 獲取 stringRedisTemplate 對象方法
*
* @return
*/
public StringRedisTemplate getStringRedisTemplate() {
return SpringContext.getBean(StringRedisTemplate.class);
}
}SpringContext 工具類方法:
/**
* @Description: SpringContext 獲取 Spring 上下文信息
* @Author: mingtian
* @CreateDate: 2020/6/8 14:59
* @Version: 1.0
*/
@Component
public class SpringContext implements ApplicationContextAware {
/**
* 打印日志
*/
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 獲取上下文對象
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContext.applicationContext = applicationContext;
logger.info("set applicationContext");
}
/**
* 獲取 applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通過 name 獲取 bean 對象
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通過 class 獲取 bean 對象
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通過 name,clazz 獲取指定的 bean 對象
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}以上二種方案都可以解決,webSocket 中 service 注入為 null 的問題。
到此這篇關(guān)于WebSocket 中使用 @Autowired 注入對應(yīng)為null的文章就介紹到這了,更多相關(guān)WebSocket @Autowired 注入為null內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus逆向工程——Generator的使用
這篇文章主要介紹了MyBatis-Plus逆向工程——Generator的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
SpringBoot自定義MessageConvert詳細講解
正在學(xué)習(xí)SpringBoot,在自定義MessageConverter時發(fā)現(xiàn):為同一個返回值類型配置多個MessageConverter時,可能會發(fā)生響應(yīng)數(shù)據(jù)格式錯誤,或406異常(客戶端無法接收相應(yīng)數(shù)據(jù))。在此記錄一下解決問題以及追蹤源碼的過程2023-01-01
MyBatis 如何配置多個別名 typeAliasesPackage
這篇文章主要介紹了MyBatis 如何配置多個別名 typeAliasesPackage,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
Sonar編譯問題對應(yīng):File [...] can''t be indexed twice.
今天小編就為大家分享一篇關(guān)于Sonar編譯問題對應(yīng):File [...] can't be indexed twice.,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12

