0

I'm working on a simple web application using spring-mvc framework.

My configuration only has one single mvc-dispatcher Servlet, (org.springframework.web.servlet.DispatcherServlet), and all my configuration is in the META-INF\mvc-dispatcher-servlet.xml; I don't have any application.xml.

Especially, the mvc-dispatcher-servlet.xml autowire all my beans.

I would like to execute a piece of code at the startup of my web application, and this code need some beans that I need to inject.

All the examples that I've found advice to implement WebApplicationInitializer or ServletContextListener. But the problem for me is that both these interface allow to execute my code before the start-up of my main unique Servlet, and therefore, before that my beans are auto-wired.

@WebListener
public class MyCustomListener implements ServletContextListener {

    @Autowired
    private MyBean myBean;

    @Override
    public void contextInitialized(ServletContextEvent sce) {

        // I have tried the following to inject the beans:
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(sce.getServletContext());

        WebApplicationContextUtils
            .getRequiredWebApplicationContext(sce.getServletContext())
            .getAutowireCapableBeanFactory()
            .autowireBean(this);

        WebApplicationContextUtils
            .getWebApplicationContext(sce.getServletContext())
            .getAutowireCapableBeanFactory()
            .autowireBean(this);

        myBean.doStuff(); //NullPointerException
    }


    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}

I've tried to inject my dependencies into the Listener, using something like WebApplicationContextUtils or SpringBeanAutowiringSupport, but my webapplication context is always null; if I'm not mistaken, it's because the FrameworkServlet of spring hasn't read the mvc-dispatcher-servlet.xml and created the webApplicationContext yet:

From FrameworkServlet.initServletBean:

// this code that create the WebapplicationContext
// is executed after my custom listener
this.webApplicationContext = initWebApplicationContext();

What is the standard way to execute code that require beans in my case (i.e. with only a single DispatcherServlet that handle all the configuration)?

Edit:

My web.xml is pretty standard:

<web-app ... >

    <display-name>Spring MVC Application</display-name>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

I tried to implement the ApplicationListener<ContextRefreshedEvent>, but the ContextRefreshedEvent is never fired when I start my server:

@WebListener
public class MyCustomListener implements ApplicationListener<ContextRefreshedEvent> { 

    @Autowired
    private MyBean myBean;

    // I don't know why this event is never fired?
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        myBean.doStuff();
    }
}

Is there a parameter that I should add in my web.xml and/or mvc-dispatcher-servlet.xml to trigger the event ?

Nicolas C
  • 1,584
  • 2
  • 17
  • 33
  • Can you post your web.xml? – Todd Jan 15 '15 at 02:06
  • A `ServletContextListener` will never work as you only have a `DispatcherServlet` that isn't ready when that component is invoked. Create a bean implementing `ApplicationListener` this event will fire when the context has been loaded and is ready. In the method you need to implement you can do whatever you want. – M. Deinum Jan 15 '15 at 07:00
  • See http://stackoverflow.com/questions/6684451/executing-a-java-class-at-application-startup-using-spring-mvc and http://stackoverflow.com/questions/2401489/execute-method-on-startup-in-spring. – M. Deinum Jan 15 '15 at 08:10
  • Nicolas, how did you use `@Autowired` in a `@WebListener`? – Jared Burrows Apr 15 '15 at 17:16

1 Answers1

0

It seems you need to execute some code after Spring context is initialized. and not before it. You could use ContextRefreshedEvent event of the ApplicationListener.

public class CustomInitializerClass implements ApplicationListener{

public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent ) {

} }
Rohit
  • 2,132
  • 1
  • 15
  • 24