Spring在多線程下@Resource註入為null的問題
多線程下@Resource註入為null
前情敘述
記錄以下這個坑,我的情況大致是這樣的,我在用webmagic寫爬蟲,在類中通過@Resoource(@Autowired也一樣)註入dao接口實例。
然後我在process方法中引用這個實例發現這個實例在這裡一直為null,然後我在測試類或者當前類的main函數中引用dao實例就沒問題,一切正常(當時 黑人問號臉???)
幾經波折,發現原因是spring和多線程安全的問題,不讓註入。因為我也沒研究過webmagic源碼,不過我個人覺得跟webmagic沒有與spring容器相關聯可能很有關系,
解決方案
我用的是很簡單暴力的方法,spring不讓自動註入,那就手動註入唄,在process方法中通過ApplicationContext獲取對應那個dao bean實例,然後可以瞭。
附上其它解決
就是我用@service或者@resposity聲明瞭一個bean,給sping管理。現在我有個需求,就是用到Thread,但是這個線程需要用我的service或者dao,然後我習慣性的在繼承瞭Thread類或者實現瞭Runnable的類裡寫瞭如下:
@Resource private MyService myService;
但是運行的時候,進入到這個線程,這個myServcie總為null,也就是註入失敗。
1.查瞭一下,有這樣的問題,原因就是spring和多線程安全的問題,不讓註入
網上的解決方案說,聲明時弄成static的。如下:
private static CustomerchangeService customerchangeService; public CustomerchangeService getCustomerchangeService() { return customerchangeService; } public void setCustomerchangeService( CustomerchangeService customerchangeService) { CustomerchangeThread.customerchangeService = customerchangeService; }
不過我這樣行不通。
2.第二種(可以)
就是我在啟動這個線程的時候,在這個線程的構造函數中把我的service實例傳過去,然後再啟動。
new MyThread(myService).start()
3.第三種(可以)
就是讓我的service或者dao的實現類實現Runnable這個接口,然後把你的線程的邏輯寫在run方法裡,啟動的時候,直接this.start()就行。註意除瞭要在service的實現類中實現Runnable接口外,還應該在service接口中繼承Runnable接口。
對於我的情況,我是直接在dao裡實現瞭Runnable,然後用的線程池啟動的,如下:pool.execute(this);
4.還有就是直接new一個實例。
不知道還有什麼解決的好辦法。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 解決Spring在Thread中註入Bean無效的問題
- Java如何固定大小的線程池
- 如何獲取所有spring管理的bean
- Spring Boot使用線程池處理上萬條數據插入功能
- Java創建多線程的8種方式集合