web-dev-qa-db-fra.com

Spring - Injection d'une dépendance dans un ServletContextListener

Je voudrais injecter une dépendance dans un ServletContextListener. Cependant, mon approche ne fonctionne pas. Je peux voir que Spring appelle ma méthode de définition, mais plus tard lorsque contextInitialized est appelé, la propriété est null.

Voici ma configuration:

Le 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: (c'est le dernier écouteur du fichier)

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

applicationContext.xml:

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

Sortie:

set prop to HELLO
Initialising listener...
null

Quelle est la bonne façon d'y parvenir?

27
dogbane

J'ai résolu ce problème en supprimant le bean d'écoute et en créant un nouveau bean pour mes propriétés. J'ai ensuite utilisé ce qui suit dans mon écouteur, pour obtenir le bean de propriétés:

@Override
public void contextInitialized(ServletContextEvent event) {

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

La réponse du dogbane (acceptée) fonctionne mais elle rend les tests difficiles à cause de la façon dont les haricots sont instanciés. Je préfère l'approche suggérée dans cette question :

@Autowired private Properties props;

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

    //Do something with props
    ...
}    
30
a.b.d

Comme mentionné précédemment, ServletContextListener est créé par le serveur et n'est donc pas géré par Spring.

Si vous souhaitez être averti du ServletContext, vous pouvez implémenter l'interface:

org.springframework.web.context.ServletContextAware
5
RicoZ

Vous ne pouvez pas avoir le printemps pour le faire, comme déjà indiqué qui est créé par le serveur. Si vous avez besoin de transmettre des paramètres à votre écouteur, vous pouvez le définir dans votre XML Web en tant que paramètre de contexte

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

Et dans l'écouteur, vous pouvez le récupérer comme ci-dessous;

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

Édition 1:

Voir le lien ci-dessous pour une autre solution possible:

Comment injecter des dépendances dans HttpSessionListener, en utilisant Spring?

1
fmucar