Spring踩坑:@Autowired自動注入service/dao為null,在listener中調用service, listener和servlet的加載先后順序


原因:@Autowired自動注入service/dao為null,原因是因為在listener中調用了service,然而 listener比servlet先加載,所以listener加載完了的時候,servlet還沒加載出來,所以Autowired為null。

解決辦法:手動獲取bean,不要自動注入。

詳細內容請繼續往下看,解決方案請跳到最后。

背景介紹

本來只是個普通的java web項目,功能是:實現MessageListener類,在onMessage()方法中,訂閱amq的數據,並通過websocket推送到前端。

后來功能延展,需要和數據庫做交互。

所以需要在onMessage()方法中,額外增加一條將收到的數據寫入數據庫。

實現邏輯

  1. 引入了spring springmvc mybatis,注意mybatis jar包和mybatis-spring jar包要兼容,mybatis-3.4是不能和mybatis-spring-1.2兼容的。

2.配置web.xml,applicationContext.xml,springmvc-servlet.xml,注意下路徑別寫錯了

3.寫service,寫dao的接口和xml

3.在實現MessageListener的類中,@Autowired一個service,service再@AutoWired一個dao。

注意一下,service可以手動實例化,就是new 一個service出來。
但是普通的spring項目不要這樣做,因為手動new出來的service,不歸spring管,在service里面@Autowired的dao,spring就不會幫我們自動注入了。
還是得從容器里面拿,
@AutoWired
Service service;

錯誤原因

就是寫在開頭的,加載順序問題。

我在listener中調用了service,我需要的加載順序是:servlet先加載,listener后加載。

但實際上加載的順序是按web.xml來的:context-param --> listeners --> filters --> servlets

所以我在Listener中自動注入service,servlet還沒加載呢,因此AutoWired的對象是null。

解決方案

這時候就不用自動注入了,手動獲取吧。

service就直接在初始化的時候全局new一個吧,這樣也可以的,主要是dao的接口實例化。
先全局一個MyDao myDao

if (myDao == null) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    myDao = ac.getBean(MyDao.class);
}

注意路徑不要寫錯了哦,要寫classpath下的路徑。

問題到這里就解決啦,腦殼大,喝杯奶茶慶祝一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM