spring mvc 中多个 dispatcherservlet 实例各自拥有独立的子 webapplicationcontext,互不继承、互不可见,但都可访问同一个父容器(root webapplicationcontext),形成“并列子容器 + 共享父容器”结构。

Spring MVC 中多个 DispatcherServlet 实例,各自拥有独立的子 WebApplicationContext(子容器),它们**互不继承、互不可见**,但**都可访问同一个父容器(Root WebApplicationContext)**。这不是“多级父子链”,而是“并列子容器 + 共享父容器”的结构。
每个 DispatcherServlet 对应一个独立子容器
在 web.xml 或基于 Java 的 Servlet 注册中,每声明一个 DispatcherServlet(如 admin-servlet、api-servlet),Spring 就会为其初始化一个专属的 WebApplicationContext。这个上下文:
- 以 servlet 名为标识,保存在
ServletContext中,key 为"org.springframework.web.servlet.FrameworkServlet.CONTEXT" + servletName; - 只加载自己配置文件(如
admin-servlet.xml)中定义的 bean,例如@Controller、@RequestMapping相关组件; - 默认不扫描其他 servlet 的 bean,彼此完全隔离——
admin-servlet找不到api-servlet里定义的 controller。
父容器是共享的根上下文
父容器由 ContextLoaderListener 初始化,只有一个,全局唯一:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 加载
context-param指定的配置(如applicationContext.xml),注册 service、dao、aop、transaction 等非 web 层 bean; - 绑定到
ServletContext,key 为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE; - 所有
DispatcherServlet子容器在创建时,都会将该父容器设为自己的parent,从而能通过getBean()或自动注入访问其中的 service bean。
查找 bean 时的委托机制
当某个 DispatcherServlet 处理请求,需要注入一个 service bean 时:
- 先在其自身子容器中查找(比如 controller、handler mapping、view resolver);
- 未找到,则自动向上委托给父容器查找(service、datasource、transactionManager 等);
- 父容器查不到,才抛出
NoSuchBeanDefinitionException; - 但反向不行:父容器无法感知任何子容器中的 bean,也不能注入 controller 或
@RequestMapping方法。
实际配置示意(web.xml 片段)
以下配置会形成 1 个父容器 + 2 个并列子容器:
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet><servlet-name>admin</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:admin-servlet.xml</param-value></init-param></servlet><servlet><servlet-name>api</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:api-servlet.xml</param-value></init-param></servlet>
此时:
– admin 和 api 容器彼此无关联;
– 二者都能注入 applicationContext.xml 中定义的 UserService;
– 但 admin 容器里的 AdminController 对 api 容器不可见,反之亦然。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










