DispatcherServlet源码分析
程序员文章站
2022-04-17 14:37:55
...
1. 继承结构:
HttpServletBean把普通的Servlet包装成Spring的bean,这样可以将init-param的值作为bean的属性注入。
FrameworkServlet完成了Spring的容器(WebApplicationContext)的初始化工作,关键方法是initWebApplicationContext()方法,并放到Servlet对象之中。
2. 初始化组件
用户没有配置组件时,将使用预定义的值。这里以HandlerMappings为例,其它组件的初始化类似:
3. 处理请求
请求到达,容器调用DispatcherServlet的service()方法,最终会调用doDispatcher()方法:
附:DispatcherServlet.properties
HttpServletBean把普通的Servlet包装成Spring的bean,这样可以将init-param的值作为bean的属性注入。
FrameworkServlet完成了Spring的容器(WebApplicationContext)的初始化工作,关键方法是initWebApplicationContext()方法,并放到Servlet对象之中。
2. 初始化组件
用户没有配置组件时,将使用预定义的值。这里以HandlerMappings为例,其它组件的初始化类似:
// 初始化 private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; if (this.detectAllHandlerMappings) { // Find all HandlerMappings in the ApplicationContext, including ancestor contexts. Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values()); OrderComparator.sort(this.handlerMappings); // 排序 } } else { try { HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); // 从上下文中获取名称为handlerMapping的映射处理器 this.handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerMapping later. } } // 确保至少有一个映射处理器 // 如果没有其它的映射处理器,预定义的(从DispatcherServlet.properties读取)将被实例化。 if (this.handlerMappings == null) { this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default"); } } }
private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties"; static { // 从属性文件加载默认组件实现。 // 内部的实现,不意味着被外部修改。 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()); } }
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) { String key = strategyInterface.getName(); String value = defaultStrategies.getProperty(key); if (value != null) { String[] classNames = StringUtils.commaDelimitedListToStringArray(value); List<T> strategies = new ArrayList<T>(classNames.length); for (String className : classNames) { try { Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader()); Object strategy = createDefaultStrategy(context, clazz); strategies.add((T) strategy); } catch (ClassNotFoundException ex) { throw new BeanInitializationException( "Could not find DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", ex); } catch (LinkageError err) { throw new BeanInitializationException( "Error loading DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]: problem with class file or dependent class", err); } } return strategies; } else { return new LinkedList<T>(); } } protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) { List<T> strategies = getDefaultStrategies(context, strategyInterface); if (strategies.size() != 1) { throw new BeanInitializationException( "DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]"); } return strategies.get(0); }
3. 处理请求
请求到达,容器调用DispatcherServlet的service()方法,最终会调用doDispatcher()方法:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; int interceptorIndex = -1; try { ModelAndView mv; boolean errorView = false; try { processedRequest = checkMultipart(request); // 检查是否multipart的请求 // 找到匹配当前请求的映射处理器。 mappedHandler = getHandler(processedRequest, false); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // 找到匹配的处理适配器。 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 如果处理器支持,处理last-modified头. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { String requestUri = urlPathHelper.getRequestUri(request); logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } // 如果是GET请求且资源自上次修改时间起未被修改 } // 调用已注册拦截器的preHandle方法。 HandlerInterceptor[] interceptors = mappedHandler.getInterceptors(); if (interceptors != null) { for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { // 调用preHandle失败 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); // 进行完成后的处理操作 return; } interceptorIndex = i; // 记录调用成功的拦截器的索引。 } } // 调用处理器的方法。 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 如果视图没有指定,根据请求生成默认视图 if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } // 逆序调用已注册拦截器的postHandle方法。 if (interceptors != null) { for (int i = interceptors.length - 1; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv); } } } catch (ModelAndViewDefiningException ex) { logger.debug("ModelAndViewDefiningException encountered", ex); mv = ex.getModelAndView(); } catch (Exception ex) { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(processedRequest, response, handler, ex); errorView = (mv != null); } // 处理器返回视图? if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); // 使用数据渲染视图 if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } // 从调用成功拦截器的索引开始,逆序调用完成后的处理。 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); } catch (Exception ex) { // 异常,手动调用完成后的处理。 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } catch (Error err) { ServletException ex = new NestedServletException("Handler processing failed", err); // 错误,手动调用完成后的处理。 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } finally { // 清理被multipart请求占用的资源。 if (processedRequest != request) { cleanupMultipart(processedRequest); } } }
附:DispatcherServlet.properties
# Default implementation classes for DispatcherServlet's strategy interfaces. # Used as fallback when no matching beans are found in the DispatcherServlet context. # Not meant to be customized by application developers. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\ org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\ org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
上一篇: 超级欠扁脑筋急转弯
下一篇: python-20 异常处理