SpringMvc的使用都会在web.xml中配置 <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup><!--大于0表示服务容器启动后,自动创建DispatcherServlet 容器--> </servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
@SuppressWarnings("serial") public class DispatcherServlet extends FrameworkServlet { 源码中它是 FrameworkServlet 的子类
@SuppressWarnings("serial") public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
FrameworkServlet又是 HttpServletBean 的子类,HttpServletBean 又是HttpServlet的子类
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware { HttpServletBean 是 HttpServlet的子类
所以DispatcherServlet本质上就是一个java servlet,里面有init,doGet,doPost,doService等一些列的方法
下面是对DispatcherServlet类的解析
private static final Properties defaultStrategies;
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
}
}
类中的静态代码块,类在被实例化的时候,执行此代码块,加载DispatcherServlet.class类同目录下的DispatcherServlet.properties properties文件,此文件是不可修改的
[]
properties,文件里面是springmvc默认加载的,用户区域解析器,样式解析器,处理者的映射,处理者的适配器,处理者的异常解析器,视图解析器等
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context); //文件解析器
initLocaleResolver(context);//区域解析器,本地化解析
initThemeResolver(context);//主题解析器
initHandlerMappings(context);//handler映射(到Controller中的menthod)
initHandlerAdapters(context);//handler适配器(执行映射对应的method)
initHandlerExceptionResolvers(context);//处理者的异常解析器
initRequestToViewNameTranslator(context);//请求到视图名称的转换,可以处理那些返回view为空的modelAndView ,它可以根据Request获取view的名称
initViewResolvers(context);//视图解析器
initFlashMapManager(context);//flash的映射管理
}
DispatcherServlet容器创建后,会执行onRefresh方法,去刷新所创建的容器,initStrategies方法则会加载 这九个默认的解析器
DisPathcherServlet的核心方法doService
@Override protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { if (logger.isDebugEnabled()) { String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : ""; logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed + " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]"); }
// Keep a snapshot of the request attributes in case of an include,
// to be able to restore the original attributes after the include.
Map<String, Object> attributesSnapshot = null; //利用map缓存Request中的Attribute内容
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap<String, Object>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
// Make framework objects available to handlers and view objects.
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
try {
doDispatch(request, response); //这个是doService中实际执行的方法
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot); //将缓存到attributesSnapshot中的值,回填到request中
}
}
}
}
doDispatch()
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest); //获取map处理器
if (mappedHandler == null || mappedHandler.getHandler() == null) {
//没有找到对应url的maping
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//根据map获取相应的适配器
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {//执行interceptor.preHandle,在处理函数之前执行的方法
return;
}
// Actually invoke the handler.,执行处理函数,即项目中的Controller中对应url的方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //获取适配器里面对应的方法,返回视图
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(request, mv);
//这里执行interceptor.postHandle,在处理函数之前执行的方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);//进行自定义异常解,视图的解析
}
catch (Exception ex) {
//捕获异常,这里执行interceptor的afterCompletion方法
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}