原因:@Autowired自動注入service/dao為null,原因是因為在listener中調用了service,然而 listener比servlet先加載,所以listener加載完了的時候,servlet還沒加載出來,所以Autowired為null。
解決辦法:手動獲取bean,不要自動注入。
詳細內容請繼續往下看,解決方案請跳到最后。
背景介紹
本來只是個普通的java web項目,功能是:實現MessageListener類,在onMessage()方法中,訂閱amq的數據,並通過websocket推送到前端。
后來功能延展,需要和數據庫做交互。
所以需要在onMessage()方法中,額外增加一條將收到的數據寫入數據庫。
實現邏輯
- 引入了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下的路徑。
問題到這里就解決啦,腦殼大,喝杯奶茶慶祝一下。