spring 依赖注入在使用 @WebListener 注释的类中不起作用

Posted

技术标签:

【中文标题】spring 依赖注入在使用 @WebListener 注释的类中不起作用【英文标题】:spring dependency injection is not working in a class annotated with @WebListener 【发布时间】:2021-12-16 05:37:45 【问题描述】:

我在实现 ServletContextListener 的 TestAppListener 类中尝试了基于构造函数的依赖注入。 我收到了这个错误 向类 [com.example.listener.TestAppListener] 的侦听器实例发送上下文初始化事件的异常

我搜索了堆栈溢出,但找不到针对这种情况的任何解决方案。请任何人帮我解决这个问题。我也将实现类放在 META-INF.services 文件夹中。我的理解是构造函数依赖注入存在一些问题,但我的情况需要这种 DI 方式,因为我想实时在启动方法中创建数据源连接。

找到我正在使用的所有课程,

@WebListener
public class TestAppListener implements ServletContextListener 

private static TestDao dao;

public TestAppListener(TestDao dao)
    this.dao = dao;

public TestAppListener()

@Override
public void contextInitialized(ServletContextEvent sce) 
    dao = ServiceLoader.load(TestDao.class).iterator().next();
    dao.startUp();
    System.out.println("Context initialized method called");


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

public interface TestDao 

void startUp();

void shutDown(); 

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


@Override
public void shutDown() 
    System.out.println("Database is initialized");

@Configuration
public class SpringConfig 

public SpringConfig() 


@Bean
public ServletListenerRegistrationBean<ServletContextListener> listenerRegistrationBean() 
    ServletListenerRegistrationBean<ServletContextListener> bean = new ServletListenerRegistrationBean<>();
    bean.setListener(new TestAppListener());
    return bean;

【问题讨论】:

【参考方案1】:

Servlet @WebListeners 在容器启动时由 Servlet 容器(tomcat/Jetty)处理。所以他们对 Spring 一无所知。

更多详情请见discussion in this issue。

解决方法是将@WebListener 替换为Spring 的@Component,这样您就可以将Spring bean(将您的Dao 声明为spring bean)直接注入到侦听器中。

顺便说一句,您必须在 Spring Boot 应用程序类中添加 @ServletComponentScan 才能激活它。

我创建了an example project 来演示@WebServlet@WebFilter@WebListener

【讨论】:

【参考方案2】:

private static TestDao dao 更改为private final TestDao dao。 Spring 不允许将静态变量用作注入的目标。此外,您的 TestDaoImpl 类必须是 Spring 配置文件中定义的组件或 bean。

【讨论】:

我不认为这是导致问题的原因。因为它不是通过弹簧注入注入静态场。虽然不推荐。

以上是关于spring 依赖注入在使用 @WebListener 注释的类中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在Maven中配置Spring依赖

spring的注入依赖

编码剖析Spring依赖注入的原理

Spring 依赖注入(注入方式)

从头认识Spring-1.1 什么是依赖注入?为什么须要依赖注入?

spring的依赖注入NC产品中也用到spring的依赖注入