[英]spring dependency injection is not working in a class annotated with @WebListener
I tried constructor based Dependency injection in TestAppListener class which implements ServletContextListener.我在实现 ServletContextListener 的 TestAppListener 类中尝试了基于构造函数的依赖注入。 I got this error Exception sending context initialized event to listener instance of class [com.example.listener.TestAppListener] .我收到此错误异常发送上下文初始化事件到类 [com.example.listener.TestAppListener] 的侦听器实例。
I searched stack overflow but I couldn't find any solution for this scenario.我搜索了堆栈溢出,但找不到针对这种情况的任何解决方案。 Please any one help me in sort out this.请任何人帮我解决这个问题。 I placed Implementation classes in META-INF.services folder also.我也在 META-INF.services 文件夹中放置了实现类。 My understanding is there is some problem in constructor dependency injection but this way of DI is need for my situation, because in real time I want to create datasource connection inside startup method.我的理解是构造函数依赖注入存在一些问题,但是我的情况需要这种 DI 方式,因为我想实时在启动方法中创建数据源连接。
Find all my classes below which i'm using,在下面找到我正在使用的所有课程,
@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;
}
} }
Change private static TestDao dao
to private final TestDao dao
.将private static TestDao dao
更改为private final TestDao dao
。 Spring doesn't allow statics to be used as targets for injection. Spring 不允许将静态用作注入目标。 Also, your TestDaoImpl
class needs to be a component or a bean defined in a Spring configuration file.此外,您的TestDaoImpl
类需要是 Spring 配置文件中定义的组件或 bean。
The Servlet @WebListener
s are handled by Servlet containers(tomcat/Jetty) when the container is starting.当容器启动时,Servlet @WebListener
由 Servlet 容器(tomcat/Jetty)处理。 So they know nothing about Spring.所以他们对Spring一无所知。
For more details, see discussion in this issue .有关更多详细信息,请参阅本期讨论。
A workaround solution is replace the @WebListener
with Spring's @Component
, thus you can inject Spring beans(declare your Dao as spring beans) into the listeners directly.一种解决方法是将@WebListener
替换为 Spring 的@Component
,因此您可以将 Spring bean(将您的 Dao 声明为 spring bean)直接注入侦听器。
BTW, you have to add @ServletComponentScan
on your Spring Boot application class to activate it.顺便说一句,您必须在 Spring Boot 应用程序类上添加@ServletComponentScan
才能激活它。
I created an example project to demo @WebServlet
, @WebFilter
and @WebListener
.我创建了一个示例项目来演示@WebServlet
、 @WebFilter
和@WebListener
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.