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()方法中,额外增加一条将收到的数据写入数据库。
实现逻辑
- 引入了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 2022-01-12 11:01 northwest 阅读(1118) 评论(0) 编辑 收藏 举报