web-dev-qa-db-fra.com

ContextLoaderListener ou pas?

Une application Web standard Spring (créée par Roo ou le modèle "Spring MVC Project") crée un fichier web.xml avec ContextLoaderListener et DispatcherServlet. Pourquoi n'utilisent-ils pas seulement le DispatcherServlet et le chargent-ils de charger la configuration complète?

Je comprends que ContextLoaderListener doit être utilisé pour charger les éléments qui ne sont pas pertinents pour le Web et que DispatcherServlet est utilisé pour charger les éléments pertinents pour le Web (contrôleurs, ...). Et ce résultat dans deux contextes: un contexte parent et un contexte enfant.

Contexte:

Je le faisais de la même manière depuis plusieurs années.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Handles Spring requests -->
<servlet>
    <servlet-name>roo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Cela a souvent causé des problèmes avec les deux contextes et les dépendances entre eux. Dans le passé, j’ai toujours pu trouver une solution et j’ai le sentiment que cela améliore toujours la structure et l’architecture du logiciel. Mais maintenant, je suis confronté à un problème avec les événements des deux contextes .

- Cependant, cela me fait repenser ce modèle de contexte, et je me demande: pourquoi devrais-je me mettre dans cette situation, pourquoi ne pas charger tous les fichiers de configuration printaniers avec un DispatcherServlet et supprimer le ContextLoaderListener complètement. (J'aurai toujours des fichiers de configuration différents, mais un seul contexte.)

Y a-t-il une raison pour ne pas supprimer le ContextLoaderListener?

122
Ralph

Dans votre cas, non, il n'y a aucune raison de conserver les ContextLoaderListener et applicationContext.xml. Si votre application fonctionne correctement avec uniquement le contexte de la servlet, cela reste plus simple.

Oui, le modèle généralement encouragé consiste à conserver les éléments non Web dans le contexte au niveau de l'application Web, mais ce n'est rien de plus qu'une convention faible.

Les seules raisons impérieuses d'utiliser le contexte au niveau de l'application Web sont les suivantes:

  • Si vous avez plusieurs DispatcherServlet devant partager des services
  • Si vous avez des servlets hérités/non-Spring qui ont besoin d'accéder aux services Spring-Wired
  • Si vous avez des filtres de servlet qui sont liés au contexte au niveau de l'application Web (par exemple, DelegatingFilterProxy, OpenEntityManagerInViewFilter, etc. de Spring Security)

Aucune de ces conditions ne s’applique à vous, la complexité supplémentaire n’est donc pas justifiée.

Soyez prudent lorsque vous ajoutez des tâches en arrière-plan au contexte du servlet, telles que des tâches planifiées, des connexions JMS, etc. Si vous oubliez d'ajouter <load-on-startup> à ton web.xml, ces tâches ne seront lancées qu'au premier accès du servlet.

86
skaffman

Je souhaite partager ce que j'ai fait sur mon application Spring-MVC:

  1. Sur le we-mvc-config.xml J'ai ajouté uniquement les classes annotées avec @Controller:

    <context:component-scan base-package="com.shunra.vcat">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
  2. Sur le applicationContext.xml fichiers j'ai ajouté tout le reste:

    <context:component-scan base-package="com.shunra.vcat">
        <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
10
Modi

Vous pouvez également configurer le contexte de l'application dans l'autre sens. Par exemple. afin de faire fonctionner le OpenEntityManagerInViewFilter. Configurez le ContextLoaderListener, puis configurez votre DispatcherServlet avec:

<servlet>
    <servlet-name>spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
</servlet>

Assurez-vous simplement que la valeur du paramètre contextConfigLocation est vide.

10
Gunnar Hillert