Context Hierarchy

Context Hierarchy

El DispatcherServlet espera un WebApplicationContext (una extensión de un ApplicationContext común) para su propia configuración. WebApplicationContext tiene un vínculo con el ServletContext y con el Servlet con el que está asociado. También está enlazado al ServletContext, de modo que las aplicaciones pueden usar métodos estáticos de RequestContextUtils para buscar el WebApplicationContext si necesitan acceder a él.

  • More details

    ¿Qué es un Servlet?

    Un Servlet es una clase Java que maneja solicitudes web (por ejemplo, peticiones HTTP). Es el núcleo de muchas aplicaciones web basadas en Java. Spring MVC usa un servlet especial llamado DispatcherServlet, que actúa como el “controlador principal” del framework.


    ¿Qué es el ServletContext?

    Piensa en el ServletContext como un entorno de aplicación web compartido para todos los servlets dentro de una misma aplicación. Es como una zona común donde los servlets pueden dejar cosas y acceder a ellas.

    • Imagina que tienes una aplicación web con varios servlets (por ejemplo, uno para usuarios, otro para productos).
    • Todos esos servlets viven dentro del mismo contenedor web (como Tomcat) y comparten el mismo ServletContext.
    • Es útil para compartir información o recursos globales, como configuraciones, rutas, archivos, etc.

    ¿Qué significa “el servlet con el que está asociado”?

    Cuando se dice que un WebApplicationContext está asociado a un servlet, se refiere a que cada servlet (como un DispatcherServlet) puede tener su propia configuración de Spring. Esa configuración vive dentro de su propio WebApplicationContext.

    • Por ejemplo:
      • El DispatcherServlet de usuarios tiene su contexto con los controladores y servicios relacionados con usuarios.
      • El DispatcherServlet de productos tiene su contexto con los controladores y servicios de productos.
      • Ambos pueden compartir un WebApplicationContext raíz (root), que contiene componentes comunes como servicios de acceso a base de datos, beans utilitarios, etc.

    ¿Qué es un WebApplicationContext?

    Es una extensión especial del ApplicationContext de Spring que está adaptada para aplicaciones web. Además de manejar beans como cualquier ApplicationContext, también sabe cómo trabajar con elementos web (por ejemplo, ServletContext, peticiones HTTP, etc.).


    ¿Y qué es eso de jerarquía de contextos?

    Spring permite tener una estructura en capas de contextos:

    1. WebApplicationContext raíz: contiene los beans comunes para toda la aplicación.
    2. WebApplicationContext hijo: uno por cada DispatcherServlet, con beans específicos para ese servlet.

    📌 Los contextos hijo heredan los beans del contexto padre, pero también pueden sobrescribirlos si necesitan una versión diferente.

Para muchas aplicaciones, tener un solo WebApplicationContext es simple y suficiente. Sin embargo, también es posible tener una jerarquía de contextos, donde un WebApplicationContext raíz se comparte entre múltiples instancias de DispatcherServlet (u otros Servlets), cada una con su propia configuración de WebApplicationContext hijo. Consulta la sección Additional Capabilities of the ApplicationContextpara más información sobre la funcionalidad de jerarquía de contextos.

El WebApplicationContext raíz suele contener beans de infraestructura, como repositorios de datos y servicios de negocio, que necesitan ser compartidos entre múltiples instancias de Servlets. Esos beans se heredan efectivamente y pueden ser sobrescritos (es decir, redefinidos) en el WebApplicationContext hijo específico de cada Servlet, que normalmente contiene beans locales para ese Servlet en particular. La siguiente imagen muestra esta relación:

image.png

El siguiente ejemplo configura una jerarquía WebApplicationContext:

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class<?>[] { RootConfig.class };
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class<?>[] { App1Config.class };
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/app1/*" };
	}
}

💡 Tip If an application context hierarchy is not required, applications can return all configuration through getRootConfigClasses() and null from getServletConfigClasses()

El siguiente ejemplo muestra el equivalente en web.xml:

<web-app>

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

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

	<servlet>
		<servlet-name>app1</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/app1-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>app1</servlet-name>
		<url-pattern>/app1/*</url-pattern>
	</servlet-mapping>

</web-app>