SpringMVC核心类DispatcherServlet

时间:2022-01-24 10:48:19

配置DispatcherServlet

要使用SpringMVC,必须在web.xml中配置好这个DispatcherServlet类

<!-- spring框架必须定义ContextLoaderListener,在启动Web容器时,自动装配Spring applicationContext.xml的配置信息 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <context-param><!-- 指定Spring上下文配置文件 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param> <servlet>
<servlet-name>Dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 指定SpringMVC配置文件 -->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc.xml</param-value>
</init-param>
</servlet> <servlet-mapping>
<!-- 指定请求的后缀,可以随意写,这里用.html作为请求后缀 -->
<servlet-name>Dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

DispatcherServlet有一些配置参数,默认情况下我们不用指定,如果需要可通过的指定:
• namespace
• contextConfigLocation
• publishContext
• publishEvents

DispatcherServlet的体系结构

•   DispatcherServlet的核心本质:是一个Servlet
• init方法在整个系统启动时运行,且只运行一次
• service方法在系统运行的过程中处于侦听模式,侦听并处理所有的Web请求

DispatcherServlet类的继承体系:

•   依次继承FrameworkServlet和HttpServletBean
• HttpServletBean是Spring对于Servlet最低层次的抽象
• FrameworkServlet则是在HttpServletBean的基础之上的进一步抽象。通过FrameworkServlet真正初始化了一个Spring的容器(WebApplicationContext),并引入到Servlet对象之中
• DispatcherServlet通过initStrategies方法查找并装配Spring容器中用户定义的组件Bean

SpringMVC核心类DispatcherServlet

查看各个类的源码:

SpringMVC核心类DispatcherServlet

HttpServletBean类的初始化源码:

@Override
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
} // Set bean properties from init parameters.
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);//这句是关键,HttpServletBean利用了Servlet的init()方法的执行特性,将一个普通的Servlet与Spring容器联系在一起,
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
throw ex;
} // Let subclasses do whatever initialization they like.
initServletBean(); if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}

FrameworkServlet类的初始化源码:

@Override
protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
if (this.logger.isInfoEnabled()) {
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
}
long startTime = System.currentTimeMillis(); try {
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();//注意这句代码
}
catch (ServletException ex) {
this.logger.error("Context initialization failed", ex);
throw ex;
}
catch (RuntimeException ex) {
this.logger.error("Context initialization failed", ex);
throw ex;
} if (this.logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " +
elapsedTime + " ms");
}
}

DispatcherServlet类的初始化源码:

protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context); //初始化上传文件解析器
initLocaleResolver(context); //初始化本地解析器
initThemeResolver(context); //初始化主题解析器
initHandlerMappings(context); //初始化处理器映射器
initHandlerAdapters(context); //初始化处理器适配器
initHandlerExceptionResolvers(context); //初始化处理器异常解析器
initRequestToViewNameTranslator(context); //初始化请求到视图名翻译器
initViewResolvers(context); //初始化视图解析器
initFlashMapManager(context); //初始化FlashMap管理器
}