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。

推薦閱讀: