¿Cuál es la diferencia entre ApplicationContext y WebApplicationContext en Spring MVC?

193

¿Cuál es la diferencia entre el contexto de aplicación y el contexto de aplicación web?

¿Soy consciente de que WebApplicationContextse usa para aplicaciones orientadas a la arquitectura Spring MVC?

¿Quiero saber para qué sirven las ApplicationContextaplicaciones MVC? ¿Y en qué tipo de frijoles se definen ApplicationContext?

Sumit Trehan
fuente
55
No creo que sea un duplicado de stackoverflow.com/questions/3652090/… Esa pregunta se refiere al contenido del web.xmlarchivo; Esta pregunta es acerca de algunas clases de primavera.
Raedwald
@ Raedwald eso no es cierto. La otra pregunta no web.xmlse refiere a las variantes de configuración del bean Spring XML de ApplicationContexty WebApplicationContext. Todas las definiciones de bean applicationContext.xmlestarán disponibles en ApplicationContextmientras que todas las definiciones de bean *-servlet.xmlestarán disponibles en a WebApplicationContext.
g00glen00b

Respuestas:

228

El contexto de la aplicación web amplió el contexto de la aplicación, que está diseñado para funcionar con el javax.servlet.ServletContext estándar para que pueda comunicarse con el contenedor.

public interface WebApplicationContext extends ApplicationContext {
    ServletContext getServletContext();
}

Los beans, instanciados en WebApplicationContext también podrán usar ServletContext si implementan la interfaz ServletContextAware

package org.springframework.web.context;
public interface ServletContextAware extends Aware { 
     void setServletContext(ServletContext servletContext);
}

Hay muchas cosas posibles para hacer con la instancia de ServletContext, por ejemplo, para acceder a los recursos WEB-INF (configuraciones xml y etc.) llamando al método getResourceAsStream (). Normalmente, todos los contextos de aplicación definidos en web.xml en una aplicación Spring de servlet son contextos de aplicación web, esto va tanto al contexto de la aplicación web raíz como al contexto de la aplicación del servlet.

Además, dependiendo de las capacidades de contexto de la aplicación web, puede hacer que su aplicación sea un poco más difícil de probar, y es posible que deba usar la clase MockServletContext para realizar pruebas.

Diferencia entre el servlet y el contexto raíz Spring le permite construir jerarquías de contexto de aplicación multinivel, por lo que el bean requerido se obtendrá del contexto padre si no está presente en el contexto de aplicación actual. En las aplicaciones web por defecto hay dos niveles de jerarquía, de raíces y de servlets: contextos Servlet y contexto raíz.

Esto le permite ejecutar algunos servicios como singletons para toda la aplicación (los beans de Spring Security y los servicios básicos de acceso a la base de datos generalmente residen aquí) y otros como servicios separados en los servlets correspondientes para evitar conflictos de nombres entre beans. Por ejemplo, un contexto de servlet servirá las páginas web y otro implementará un servicio web sin estado.

Esta separación de dos niveles sale de la caja cuando usa las clases de servlet de primavera: para configurar el contexto de la aplicación raíz, debe usar la etiqueta context-param en su web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/root-context.xml
            /WEB-INF/applicationContext-security.xml
    </param-value>
</context-param>

(El contexto de la aplicación raíz es creado por ContextLoaderListener que se declara en web.xml

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> 

) y la etiqueta de servlet para los contextos de aplicación de servlet

<servlet>
   <servlet-name>myservlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>app-servlet.xml</param-value>
   </init-param>
</servlet>

Tenga en cuenta que si se omite init-param, spring usará myservlet-servlet.xml en este ejemplo.

Consulte también: Diferencia entre applicationContext.xml y spring-servlet.xml en Spring Framework

Boris Treukhov
fuente
2
Muchas gracias por la respuesta. He oído que hay dos tipos de contextos que también se usan para una aplicación web. Uno sirve como contexto de aplicación raíz donde se proporcionan definiciones no relacionadas con la web, por ejemplo, servicio, configuraciones de dao, etc., y el otro es para una configuración específica de la web, como asignaciones de controladores, etc. El anterior sirve como contexto principal y el último sirve como contexto secundario . Quiero saber cómo declarar esta estructura. He oído hablar de algunas devoluciones de llamada de ContextListener. Pero no estoy muy claro al respecto.
Sumit Trehan
1
Dicha estructura está codificada en las herramientas de servlet Spring, siempre hay al menos dos contextos de aplicación en la aplicación web Spring, vea la respuesta actualizada, espero que ayude.
Boris Treukhov
Excelente descripción ... tuve algunas dudas sobre este escenario ... como estoy en la etapa inicial, encontré su respuesta útil para obtener algunos conocimientos ...
user533
"el bean requerido se obtendrá del contexto principal si no está presente en el contexto de la aplicación actual". ¿Puedes explicar cómo? ¿Cómo un contexto de aplicación web puede acceder a beans en contexto de aplicación raíz? Enlace a algún ejemplo?
anir
14

Volviendo a los días de Servlet, web.xml solo puede tener uno <context-param>, por lo que solo se crea un objeto de contexto cuando el servidor carga una aplicación y los datos en ese contexto se comparten entre todos los recursos (Ej: Servlets y JSP). Es lo mismo que tener el nombre del controlador de la base de datos en el contexto, que no cambiará. De manera similar, cuando declaramos el parámetro contextConfigLocation en <contex-param>Spring crea un objeto Contexto de aplicación.

 <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.myApp.ApplicationContext</param-value>
 </context-param>

Puede tener múltiples Servlets en una aplicación. Por ejemplo, es posible que desee manejar / seguro / * solicitudes de una manera y / non-seucre / * de otra manera. Para cada uno de estos Servlets, puede tener un objeto de contexto, que es un WebApplicationContext.

<servlet>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.secure.SecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <url-pattern>/secure/*</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.non-secure.NonSecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <url-pattern>/non-secure/*</url-patten>
</servlet-mapping>
Ben Tennyson
fuente
13

La respuesta aceptada es válida, pero hay una explicación oficial sobre esto:

WebApplicationContext es una extensión del ApplicationContext simple que tiene algunas características adicionales necesarias para las aplicaciones web. Se diferencia de un ApplicationContext normal en que es capaz de resolver temas (consulte Uso de temas), y que sabe con qué Servlet está asociado (al tener un enlace al ServletContext). WebApplicationContext está enlazado en ServletContext, y al usar métodos estáticos en la clase RequestContextUtils, siempre puede buscar el WebApplicationContext si necesita acceder a él.

Citado de la referencia del marco web de Spring

Por cierto contexto servlet y raíz son tanto WebApplicationContext:

Jerarquía de contexto típica en Spring Web MVC

Nick Allen
fuente
6

ApplicationContext (contexto de aplicación raíz): cada aplicación web Spring MVC tiene un archivo applicationContext.xml que se configura como la raíz de la configuración de contexto. Spring carga este archivo y crea un applicationContext para toda la aplicación. Este archivo lo carga ContextLoaderListener que está configurado como parámetro de contexto en el archivo web.xml. Y solo habrá un applicationContext por aplicación web.

WebApplicationContext: WebApplicationContext es un contexto de aplicación compatible con la web, es decir, tiene información de contexto de servlet. Una sola aplicación web puede tener múltiples WebApplicationContext y cada servlet Dispatcher (que es el controlador frontal de la arquitectura Spring MVC) está asociado con un WebApplicationContext. El archivo de configuración webApplicationContext * -servlet.xml es específico de un DispatcherServlet. Y dado que una aplicación web puede tener más de un servlet despachador configurado para atender múltiples solicitudes, puede haber más de un archivo webApplicationContext por aplicación web.

Hetal Rachh
fuente
3

El contexto de aplicación web , especificado por la WebApplicationContextinterfaz, es un contexto de aplicación Spring para aplicaciones web. Tiene todas las propiedades de un contexto de aplicación Spring regular, dado que la WebApplicationContextinterfaz extiende la ApplicationContextinterfaz y agrega un método para recuperar la API de Servlet estándar ServletContextpara la aplicación web.

Además de los ámbitos estándar de Spring Bean singletony prototype, hay tres ámbitos adicionales disponibles en un contexto de aplicación web:

  • request- define una sola definición de bean para el ciclo de vida de una sola solicitud HTTP; es decir, cada solicitud HTTP tiene su propia instancia de un bean creado a partir de una definición de bean único
  • session - define una definición de bean único para el ciclo de vida de una sesión HTTP
  • application - Alcanza una definición de bean único al ciclo de vida de un ServletContext
DimaSan
fuente