You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@WebListener注解类中Spring构造函数依赖注入失效问题求助

错误根因

  1. 你注册TestAppListener时直接调用无参构造new TestAppListener(),没有传入TestDao实例,且代码同时混用Spring依赖注入和JDK的ServiceLoader逻辑,执行contextInitialized时ServiceLoader.load(TestDao.class).iterator().next()如果找不到实现类会直接抛出异常,和你预期的构造注入逻辑完全冲突。
  2. TestDaoImpl没有被注册为Spring Bean,Spring容器无法识别该实现类用于构造注入。
  3. 同时使用@WebListener和ServletListenerRegistrationBean会导致Listener被重复注册,多余的注册流程会直接调用无参构造创建Listener实例,触发空指针或ServiceLoader加载失败问题。
  4. 把TestDao声明为static修饰的静态变量不符合Spring实例注入的设计规范,会导致多上下文场景下的变量覆盖问题。

修复步骤

1. 修正TestAppListener代码

移除ServiceLoader相关逻辑,删除无参构造,移除变量的static修饰,同时删除类上的@WebListener注解,也不需要再保留META-INF/services下的ServiceLoader配置,避免逻辑冲突:

public class TestAppListener implements ServletContextListener {

    private final TestDao dao;

    // 仅保留带参构造用于Spring注入
    public TestAppListener(TestDao dao){
        this.dao = dao;
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        dao.startUp();
        System.out.println("Context initialized method called");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Context destroyed method called");
        dao.shutDown();
    }
}

2. 把TestDaoImpl注册为Spring Bean

给TestDaoImpl添加@Repository注解,或者在配置类中注册为Bean:

@Repository
public class TestDaoImpl implements TestDao {
    @Override
    public void startUp() {
        System.out.println("Database is initialized");
    }

    @Override
    public void shutDown() {
        System.out.println("Database is destroyed");
    }
}

3. 修正SpringConfig中的Listener注册逻辑

直接将Spring容器中的TestDao实例注入到TestAppListener的构造函数中:

@Configuration
public class SpringConfig {

    @Bean
    public ServletListenerRegistrationBean<ServletContextListener> listenerRegistrationBean(TestDao testDao) {
        ServletListenerRegistrationBean<ServletContextListener> bean = new ServletListenerRegistrationBean<>();
        // 使用带参构造传入Spring管理的TestDao实例
        bean.setListener(new TestAppListener(testDao));
        return bean;
    }
}

完成以上修改后,启动时Spring会自动注入TestDao实例到Listener中,不会再触发初始化异常。

内容的提问来源于stack exchange,提问作者mitco94

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 11:27:02