Spring - Injecting a dependency into a ServletContextListener

42,462

Solution 1

I resolved this by removing the listener bean and creating a new bean for my properties. I then used the following in my listener, to get the properties bean:

@Override
public void contextInitialized(ServletContextEvent event) {

    final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
    final Properties props = (Properties)springContext.getBean("myProps");
}

Solution 2

The dogbane's answer (accepted) works but it makes testing difficult because of the way beans are instantiated. I prefere the approach suggested in this question :

@Autowired private Properties props;

@Override
public void contextInitialized(ServletContextEvent sce) {
    WebApplicationContextUtils
        .getRequiredWebApplicationContext(sce.getServletContext())
        .getAutowireCapableBeanFactory()
        .autowireBean(this);

    //Do something with props
    ...
}    

Solution 3

As mentioned before the ServletContextListener is created by the server and so it is not managed by spring.

If you wish to be notified of the ServletContext, you can implement the interface:

org.springframework.web.context.ServletContextAware

Solution 4

You cant have spring to do that, as already stated that is created by the server. If you need to pass params to your listener, you can define it in your web xml as a context-param

<context-param> 
        <param-name>parameterName</param-name>
        <param-value>parameterValue</param-value>
    </context-param>

And in the Listener you can retrieve it like below;

 event.getServletContext().getInitParameter("parameterName")

Edit 1:

See the link below for another possible solution:

How to inject dependencies into HttpSessionListener, using Spring?

Share:
42,462

Related videos on Youtube

dogbane
Author by

dogbane

Programmer

Updated on July 09, 2022

Comments

  • dogbane
    dogbane almost 2 years

    I would like to inject a dependency into a ServletContextListener. However, my approach is not working. I can see that Spring is calling my setter method, but later on when contextInitialized is called, the property is null.

    Here is my set up:

    The ServletContextListener:

    public class MyListener implements ServletContextListener{
    
        private String prop;
    
        /* (non-Javadoc)
         * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
         */
        @Override
        public void contextInitialized(ServletContextEvent event) {
            System.out.println("Initialising listener...");
            System.out.println(prop);
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent event) {
        }
    
        public void setProp(String val) {
            System.out.println("set prop to " + prop);
            prop = val;
        }
    }
    

    web.xml: (this is the last listener in the file)

    <listener>
      <listener-class>MyListener</listener-class>
    </listener> 
    

    applicationContext.xml:

    <bean id="listener" class="MyListener">
      <property name="prop" value="HELLO" />
    </bean>  
    

    Output:

    set prop to HELLO
    Initialising listener...
    null
    

    What is the correct way to achieve this?

  • dogbane
    dogbane over 13 years
    Sorry, I don't understand why I need to implement ServletContextAware? My listener already has a reference to the ServletContext because it is present in the ServletContextEvent.
  • dogbane
    dogbane over 13 years
    I'd like to pass a bean in. Not name-values.
  • fmucar
    fmucar over 13 years
    @dogbane see the edited post. Added a new link that may be useful for your case as well
  • RicoZ
    RicoZ over 13 years
    if you use the listener, you cannot inject spring dependencies, so the ServletContextAware is an alternative
  • a.b.d
    a.b.d almost 12 years
    The way beans are instantiated make testing difficult, see my answer.
  • christopher
    christopher over 10 years
    I know this is old,but for future readers, when I attempt this I get an IllegalStateException with the message No WebApplicationContext found: no ContextLoaderListener registered?
  • Wouter Lievens
    Wouter Lievens over 10 years
    Chris: I get the same problem!
  • asgs
    asgs almost 9 years
    @christopher @Wouter You'll have to include the Spring's ContextLoaderListener to fix it as detailed in this post.

Related