SpringMVC 面试高频!WebApplicationContext 原理与实战解析

63 阅读4分钟



故事开篇:面试现场的意外考题

上周,我去面试了一家知名互联网公司。抱着“自信满满,不怕难题”的心态,稳步走进面试室。然而,面试官一开口,我就感觉有点不妙:

“你能介绍一下 SpringMVC 中的 WebApplicationContext 吗?”

我脑子里瞬间闪过无数个词条,什么 ApplicationContext、WebApplicationContext、DispatcherServlet……我的思维就像一团乱麻。可不能掉链子啊!

我微微一笑,深吸一口气,脑海中飞速整理着知识点:

“WebApplicationContext 是 SpringMVC 中特有的子容器,它继承了 ApplicationContext,并在此基础上进行扩展,专门用于 Web 环境下的应用程序上下文管理……”

面试官点点头,让我继续说下去。于是,我从容不迫地开始了我的解答。

WebApplicationContext 是什么?

其实,说到 WebApplicationContext,就得先提提 ApplicationContext。我们都知道,ApplicationContext 是 Spring 中非常核心的接口,提供了容器管理、Bean 加载、事件发布等功能。

但是,在 Web 场景 中,Spring 提供了一个更加专业的容器,那就是 WebApplicationContext。简单来说,WebApplicationContext 是 ApplicationContext 的子接口,专门用于 Web 应用环境

1. 特性扩展

它不仅继承了 ApplicationContext 的所有功能,还提供了一些额外的方法,例如:

  • 访问 ServletContext 对象。
  • 访问与 Web 相关的配置信息。

2. 常见实现类:XmlWebApplicationContext

在实际项目中,我们最常用的是 XmlWebApplicationContext,它可以加载基于 XML 文件的配置。

WebApplicationContext 的加载过程

面试官听到这儿,似乎有点满意,但他接着问:

“那 WebApplicationContext 是怎么加载的呢?”

我心里暗暗庆幸,正好最近做了复习,于是继续答道:

SpringMVC 中,WebApplicationContext 的初始化通常是在 DispatcherServlet 加载时完成的。它的整个过程分为几个步骤:

1. DispatcherServlet 初始化

当 DispatcherServlet 初始化时,首先会调用 initWebApplicationContext() 方法。

2. 获取 WebApplicationContext

Servlet 会去检查在 Web.xml 文件中配置的 contextConfigLocation,如果存在,则加载配置文件。

3. 加载配置文件

通过 ContextLoaderListener 或者 ContextLoader 来加载 SpringMVC 的上下文。

4. 存入 ServletContext

最后,将加载完的 WebApplicationContext 存入 ServletContext 中,便于在整个应用中使用。

(代码示例)

父子容器的“亲子关系”

“对了,WebApplicationContext 和 ApplicationContext 之间有什么关系?”面试官继续追问。

我微微一笑:

“这就涉及到 SpringMVC 中的父子容器设计了!”

1. 父容器:根容器(Root WebApplicationContext)

由 ContextLoaderListener 加载的容器,存放一些全局 Bean,比如数据源、事务管理器。

2. 子容器:WebApplicationContext

由每个 DispatcherServlet 创建,属于子容器。子容器可以访问父容器中的 Bean,而父容器无法访问子容器中的 Bean。

(举个栗子)

假如我们在父容器中定义了一个数据源 Bean,那么在子容器的 Controller 中是可以直接注入和使用的。

但是,如果在子容器中定义了一个 Controller 专用的 Bean,是无法在父容器中直接获取的。

面试官的补刀:多 DispatcherServlet 场景

“那如果有多个 DispatcherServlet,它们各自的 WebApplicationContext 之间会互相影响吗?”

我略微一愣,马上回忆起项目中的场景:

“不会。每个 DispatcherServlet 都会创建独立的 WebApplicationContext 实例,互不影响。”

我补充道:

  • 各自独立: 彼此之间的数据和 Bean 是隔离的。
  • 父容器共享: 多个 WebApplicationContext 可以共用一个父容器。

面试官点赞:实战经验分享

面试官听完表示很满意,并表示他们的项目中确实遇到了多个 DispatcherServlet 独立配置的问题。我顺势补充:

“可以在 Web.xml 中为每个 DispatcherServlet 配置不同的 contextConfigLocation,这样可以灵活管理多个子容器。”

总结:WebApplicationContext,面试必备!

走出面试室,我心里感觉轻松不少。回顾这次面试,WebApplicationContext 真是个面试常客!

  • 它是 ApplicationContext 的扩展,专为 Web 场景设计。
  • 与 DispatcherServlet 紧密关联,加载和初始化时息息相关。
  • 多 DispatcherServlet 独立运行,容器间不会互相干扰。

在接下来的面试复习中,我决定多花时间在一些“常考却容易疏忽”的知识点上,比如 SpringMVC 的底层原理和容器机制。希望大家也能从这篇文章中学到一些干货,面试时不再慌!

END

如果这篇文章对你有帮助,点个赞或者分享给朋友吧!咱们下期继续聊聊 Spring 的其他面试题!

希望你喜欢这篇风格活泼的技术分享文章!如果有其他面试题或技术点想聊,随时告诉我哦~

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!