Listener中使用Spring注解失败,空指针

在Web项目启动时,为实现初始化操作,如将数据库数据存入Redis,作者遇到了Listener中使用Spring注解失败导致的空指针异常。问题源于Listener由Servlet容器而非Spring容器管理,导致@Autowired注解无效。解决方案是利用WebApplicationContextUtils获取Spring容器引用,确保在Listener初始化时Spring对象已加载。但需注意Listener的加载顺序,需要在web.xml中先配置初始化Spring容器的Listener,再配置自定义Listener。在Web Server容器内的Servlet、Filter和Listener都不是Spring管理的,不能直接使用Spring注解注入对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己踩坑

  在做web项目时,我们有时候需要在项目启动的时候需要做一些初始化的操作,例如:读取数据库数据放入redis缓存中,自己就是在这个地方碰到了问题,主要是自己对tomcat容器中的结构不熟悉,当时找了很多资料才解决了。

  先看代码

public class LoadDbToRedisListener extends ContextLoaderListener {

    @Autowired
    private LoadDbToRedisService loadToRedisService;

    /** 日志 */
    private static final Logger LOG = LoggerFactory.getLogger(LoadDbToRedisListener.class);
    /**
     * 重写ContextLoaderListener的contextInitialized方法
     * @param event 事件
     */
    @Override
    public void contextInitialized(ServletContextEvent event) {
        super.contextInitialized(event);

        try {
           
            loadToRedisService.loadCodesToRedis();
        }catch (Exception e){
            LOG.info("数据库载入缓存失败" + e.toString());
        }
    }
}

  一开始我使用了上面的代码,但是执行不成功数据存人redis失败,debug进来发现loadToRedisService对象是空。翻阅资料发现Listener对象的生命周期是由servlet容器管理的,加载的时候servlet容器并不认识@Autowired注解,因此造成对象为空,loadToRedisService对象的声明周期是由Srping容器管理。

解决

public class LoadDbToRedisListener extends ContextLoaderListener {

    private static final Logger LOG = LoggerFactory.getLogger(LoadDbToRedisListener.class);
    /**
     * 重写ContextLoaderListener的contextInitialized方法
     * @param event 事件
     */
    @Override
    public void contextInitialized(ServletContextEvent event) {
        super.contextInitialized(event);

        try {
            LoadDbToRedisService loadToRedisService = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()).getBean(LoadDbToRedisServiceImpl.class);


            loadToRedisService.loadCodesToRedis();
        }catch (Exception e){
            LOG.info("数据库载入缓存失败" + e.toString());
        }
    }
}

  使用WebApplicationContextUtils工具类引入loadToRedisService对象成功,该工具类的作用是获取到spring容器的引用。

但是要注意的一点是该Listener初始化时要确保spring中的对象已经加载完成,否则同样会造成空指针。需要在web.xml文件中先配置初始化spring容器的Listener,然后在配置自己的Listener。

最后还要说明:在web Server容器中,无论是Servlet,Filter,还是Listener都不是Spring容器管理的,因此我们都无法在这些类中直接使用Spring注解的方式来注入我们需要的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值