⭐表示重要。
第一章:Servlet 生命周期回顾

| 生命周期环节 | 调用的方法 | 时机 | 次数 |
|---|---|---|---|
| 创建对象 | 无参构造器 | 默认:第一次请求,可以修改为Web应用启动时 | 一次 |
| 初始化 | init(ServletConfig servletConfig) | 创建对象后 | 一次 |
| 处理请求 | service(ServletRequest servletRequest, ServletResponse servletResponse) | 接收到请求后 | 多次 |
| 清理操作 | destroy() | Web应用卸载之前 | 一次 |
第二章:初始化操作调用路线图
2.1 类和接口之间的关系

2.2 调用线路图
- 调用线路图显示是方法调用的顺序,但是实际运行的时候本质上都是调用 DispatcherServlet 对象的方法。包括这里涉及到的接口的方法,也不是去调用接口中的『抽象方法』。毕竟抽象方法是没法执行的。抽象方法一定是在某个实现类中有具体实现才能被调用。
- 而对于最终的实现类:DispatcherServlet 来说,所有父类的方法最后也都是在 DispatcherServlet 对象中被调用的。

第三章:IOC 容器的创建
- 所在类:org.springframework.web.servlet.FrameworkServlet。
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {...protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {Class<?> contextClass = getContextClass();if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {throw new ApplicationContextException("Fatal initialization error in servlet with name '" + getServletName() +"': custom WebApplicationContext class [" + contextClass.getName() +"] is not of type ConfigurableWebApplicationContext");}// 创建 IOC 容器ConfigurableWebApplicationContext wac =(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);wac.setEnvironment(getEnvironment());// 设置父容器wac.setParent(parent);String configLocation = getContextConfigLocation();if (configLocation != null) {wac.setConfigLocation(configLocation);}configureAndRefreshWebApplicationContext(wac);return wac;}}
第四章:将 IOC 容器对象存入应用域
- 所在类:org.springframework.web.servlet.FrameworkServlet
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {...protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;if (this.webApplicationContext != null) {// A context instance was injected at construction time -> use itwac = this.webApplicationContext;if (wac instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;if (!cwac.isActive()) {// The context has not yet been refreshed -> provide services such as// setting the parent context, setting the application context id, etcif (cwac.getParent() == null) {// The context instance was injected without an explicit parent -> set// the root application context (if any; may be null) as the parentcwac.setParent(rootContext);}configureAndRefreshWebApplicationContext(cwac);}}}if (wac == null) {// 获取 IOC 容器wac = findWebApplicationContext();}if (wac == null) {// 创建 IOC 容器wac = createWebApplicationContext(rootContext);}if (!this.refreshEventReceived) {// Either the context is not a ConfigurableApplicationContext with refresh// support or the context injected at construction time had already been// refreshed -> trigger initial onRefresh manually here.synchronized (this.onRefreshMonitor) {onRefresh(wac);}}if (this.publishContext) {// 获取存入应用域时专用的属性名String attrName = getServletContextAttributeName();// 存入getServletContext().setAttribute(attrName, wac);}return wac;}}
- 看到这一点的意义:SpringMVC 有一个工具方法,可以从应用域获取 IOC 容器对象的引用。
- 工具类:org.springframework.web.context.support.WebApplicationContextUtils。
- 工具方法:getWebApplicationContext()。
public abstract class WebApplicationContextUtils {...@Nullablepublic static WebApplicationContext getWebApplicationContext(ServletContext sc) {return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);}}
第五章:请求映射初始化
- FrameworkServlet.createWebApplicationContext() —> FrameworkServlet.configureAndRefreshWebApplicationContext() —> wac.refresh(); —> org.springframework.web.servlet.DispatcherServlet.initStrategies() —> org.springframework.web.servlet.DispatcherServlet.initHandlerMappings() 。

第六章:总结
- 整个启动过程我们关心如下要点:
- ① DispatcherServlet 本质上是一个 Servlet,所以天然的遵循 Servlet 的生命周期。所以宏观上是 Servlet 生命周期来进行调度。
- ② DispatcherServlet 的父类是 FrameworkServlet。
- FrameworkServlet 负责框架本身相关的创建和初始化。
- DispatcherServlet 负责请求处理相关的初始化。
- ③ FrameworkServlet 创建 IOC 容器对象之后会存入应用域。
- ④ FrameworkServlet 完成初始化会调用 IOC 容器的刷新方法。
- ⑤ 刷新方法完成触发刷新事件,在刷新事件的响应函数中,调用 DispatcherServlet 的初始化方法。
- ⑥ 在 DispatcherServlet 的初始化方法中初始化了请求映射等。
