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下的路径。

问题到这里就解决啦,脑壳大,喝杯奶茶庆祝一下。

posted on   northwest  阅读(1139)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示