先贴出Spring 官方文档对父子容器的描述:
官方文档地址
何为根容器?
在Spring MVC场景中,官方对根容器的定义是用来管理基础设施Bean,例如需要跨多个Servlet实例共享的DAO或者Service。
何为子容器?
在Spring MVC场景中,官方对子容器的定义是Servlet级别的,因为Spring MVC是基于Servlet的,而我们都知道Servlet可以通过 标签来指定对不同请求的处理,而每个Servlet持有的子容器管理的视图解析器、控制器、处理器映射器、处理器适配器都不相同,这些是高度差异化的Bean,没必要去放到根容器中进行管理。
以请求处理器映射器(HandlerMapping)为例,该接口存在多个实现类(这里只贴出了一部分实现类),只不过通常都是使用@RequestMapping或@GetMapping、@PostMapping、@PutMapping等等这种方式,这种方式对应的请求处理器映射器就是RequestMappingHandlerMappig,但也可以使用根据BeanName来做请求路径的映射,这种方式的请求处理器映射器就是BeanNameHandlerMapping。
只不过这种根据BeanName来做请求路径映射的方式几乎没人使用,但是SpringMVC提供了这种选择。
假设应用程序中定义了N个Servlet,一个Servlet对应的Controller使用@RequestMapping这种方式,另一个Servlet对应的Controller使用根据beanName来进行映射,另一个Servlet所对应的Controller使用基于实现Controller接口这种方式,这不就是高度差异化的Bean吗?
总结
只所以存在父子容器是因为每个Servlet持有的子容器所管理的视图解析器、控制器、处理器映射器、处理器适配器都不相同,这些都是高度差异化的Bean,因此没必要放到同一个IoC容器中去进行管理。
根IoC容器中管理的Bean应该是通用的Service和Dao等其他基础服务,整个应用程序中只应该存在一个根容器,但可以存在多个子容器,它们之间是1:N关系。
需注意的是这只是Spring MVC给出的一种规范建议,并没有强制约束必须这么做。