ContextLoaderListener ou não?

Um aplicativo da Web padrão de molas (criado pelo Roo ou pelo modelo “Spring MVC Project”) cria um web.xml com ContextLoaderListener e DispatcherServlet . Por que eles não apenas usam o DispatcherServlet e o fazem para carregar a configuração completa?

Eu entendo que o ContextLoaderListener deve ser usado para carregar o material que não é relevante para a Web e o DispatcherServlet é usado para carregar o material relevante da web (Controllers, …). E esse resultado em dois contextos: um pai e um contexto filho.

Fundo:

Eu estava fazendo isso de maneira padrão por vários anos.

  contextConfigLocation classpath*:META-INF/spring/applicationContext*.xml    org.springframework.web.context.ContextLoaderListener    roo org.springframework.web.servlet.DispatcherServlet  contextConfigLocation WEB-INF/spring/webmvc-config.xml  1  

Isso costumava causar problemas com os dois contextos e as dependencies entre eles. No passado, sempre fui capaz de encontrar uma solução e tenho a forte impressão de que isso torna a estrutura / arquitetura do software sempre melhor. Mas agora estou enfrentando um problema com os events dos dois contextos .

– No entanto, isso faz com que eu repense esse padrão de dois contextos, e estou me perguntando: por que eu deveria me meter nesse problema, por que não carregar todos os arquivos de configuração do Spring com um DispatcherServlet e remover completamente o ContextLoaderListener ? (Eu ainda vou ter arquivos de configuração diferentes, mas apenas um contexto.)

Existe alguma razão para não remover o ContextLoaderListener ?

No seu caso, não, não há razão para manter o ContextLoaderListener e applicationContext.xml . Se o seu aplicativo funciona bem apenas com o contexto do servlet, ele fica mais simples.

Sim, o padrão geralmente incentivado é manter coisas não relacionadas à Web no contexto do nível webapp, mas nada mais é do que uma convenção fraca.

As únicas razões convincentes para usar o contexto no nível da webapp são:

  • Se você tiver vários DispatcherServlet que precisam compartilhar serviços
  • Se você tiver servlets herdados / não-Spring que precisem de access a serviços Spring-wired
  • Se você tiver filtros de servlet que se ligam ao contexto de nível webapp (por exemplo, DelegatingFilterProxy do Spring Security, OpenEntityManagerInViewFilter , etc)

Nenhum destes se aplica a você, então a complexidade extra é injustificada.

Apenas tome cuidado ao adicionar tarefas em segundo plano ao contexto do servlet, como tarefas planejadas, conexões JMS, etc. Se você esquecer de adicionar ao seu web.xml , essas tarefas não serão iniciadas até o primeiro access do servlet.

Você pode configurar o contexto do aplicativo também. Por exemplo, para fazer o OpenEntityManagerInViewFilter funcionar. Configure o ContextLoaderListener e configure seu DispatcherServlet com:

  spring-mvc org.springframework.web.servlet.DispatcherServlet  contextConfigLocation    

Apenas certifique-se de que o valor do parâmetro contextConfigLocation esteja vazio.

Eu quero compartilhar o que eu fiz no meu aplicativo Spring-MVC:

  1. No we-mvc-config.xml eu adicionei apenas as classs anotadas com @Controller:

        
  2. Nos arquivos applicationContext.xml , adicionei todo o resto: