I tried constructor based Dependency injection in TestAppListener class which implements ServletContextListener. I got this error Exception sending context initialized event to listener instance of class [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. 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.
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;
}
}
CodePudding user response:
Change private static TestDao dao
to private final TestDao dao
. Spring doesn't allow statics to be used as targets for injection. Also, your TestDaoImpl
class needs to be a component or a bean defined in a Spring configuration file.
CodePudding user response:
The Servlet @WebListener
s are handled by Servlet containers(tomcat/Jetty) when the container is starting. So they know nothing about 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.
BTW, you have to add @ServletComponentScan
on your Spring Boot application class to activate it.
I created an example project to demo @WebServlet
, @WebFilter
and @WebListener
.