初始化(init)
// Set bean properties from init parameters.
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
/*
用BeanWrapperImpl对象包装DispatcherServlet
*/
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); // org.springframework.beans.BeanWrapperImpl
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment())); // customEditors[Resource.class]
initBeanWrapper(bw); // 空方法
/*
把web.xml中的配置设置到 org.springframework.web.servlet.DispatcherServlet
*/
bw.setPropertyValues(pvs, true);
} catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
throw ex;
}
/*
1、获取在ContextLoaderListener初始化的 XmlWebApplicationContext
2、创建《子上下文》
ConfigurableWebApplicationContext wac = new XmlWebApplicationContext(); // 实例化
wac.setEnvironment(getEnvironment());
wac.setParent(parent); // 设置对父类的依赖
wac.setConfigLocation(getContextConfigLocation());
configureAndRefreshWebApplicationContext(wac); // !!!!
{
1、给上下文设置id
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(getServletContext().getContextPath()) + '/' + getServletName());
2、设置servlet的属性
wac.setServletContext(getServletContext());
wac.setServletConfig(getServletConfig());
wac.setNamespace(getNamespace());
3、设置监听器
wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));
4、设置属性源
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
}
5、应用初始化器、刷新《子上下文》
postProcessWebApplicationContext(wac); // 空方法
applyInitializers(wac); // 应用初始化器 !!!!
wac.refresh();
{
// 。。。同 XmlWebApplicationContext 。。。
// 解析applicationContext.xml文件 。。。
// 扫描bean,调用PostProcessors 。。。
// 启动《实现SmartLifecycle接口且配置自动启动的》的bean 。。。
// 等等。。。
// 。。。。
}
}
3、刷新《子上下文》
// 识别applicationContext.xml文件中配置的一些bean,如果没有配置,就是使用默认的
initMultipartResolver(context);
// this == DispatcherServlet
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
initLocaleResolver(context);
// this == DispatcherServlet
this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
initThemeResolver(context);
this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
initHandlerMappings(context); // 获取处理器映射
1、获取applicationContext.xml实现 HandlerMapping 接口的bean列表
2、如果1没获取到,走默认策略
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ 根据xml文件中配置的beanName来匹配
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping !!!已经过期 -- 根据类上的@RequestMapping注解来匹配
initHandlerAdapters(context);
1、获取applicationContext.xml实现 HandlerAdapter 接口的bean列表
2、如果1没获取到,走默认策略
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
initHandlerExceptionResolvers(context);
1、获取applicationContext.xml实现 HandlerExceptionResolver 接口的bean列表
2、如果1没获取到,走默认策略
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
initRequestToViewNameTranslator(context);
1、获取applicationContext.xml实现 RequestToViewNameTranslator 接口的bean
this.viewNameTranslator = context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
2、如果1没获取到,走默认策略
org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
initViewResolvers(context);
1、获取applicationContext.xml实现 ViewResolver 接口的bean列表
2、如果1没获取到,走默认策略
org.springframework.web.servlet.view.InternalResourceViewResolver
initFlashMapManager(context);
1、获取applicationContext.xml实现 FlashMapManager 接口的bean列
this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
2、如果1没获取到,走默认策略
org.springframework.web.servlet.support.SessionFlashMapManager
*/
// Let subclasses do whatever initialization they like.
initServletBean(); // !!!!
接收请求(processRequest)
/*
用 SimpleLocaleContext 包装 request.getLocale()
*/
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = buildLocaleContext(request); // 本地
/*
用 ServletRequestAttributes 包装 request、response对象
*/
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes); // 本地化
/*
创建 WebAsyncManager 对象,并设置到 request
*/
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); // 异步
/*
设置 asyncManager 的拦截器
*/
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
/*
设置 localeContext、requestAttributes 到当前上下文
*/
initContextHolders(request, localeContext, requestAttributes); // 多少线程“参数本地化”
try {
/*
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) { // “include”请求
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()); // !!!! getWebApplicationContext() === org.springframework.web.context.support.XmlWebApplicationContext
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver); // org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver); // org.springframework.web.servlet.theme.FixedThemeResolver
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource()); // !!!! getThemeSource() === org.springframework.web.context.support.XmlWebApplicationContext
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response); // org.springframework.web.servlet.support.SessionFlashMapManager
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);
doDispatch(request, response); // !!!
{
try {
try {
1、处理请类型
processedRequest = checkMultipart(request); // 检查是否Multipart类型(如:文件上传),如果是,就进行解析
2、获取当前请求的 mappedHandler(HandlerExecutionChain)
mappedHandler = getHandler(processedRequest); // 决策一个适合processedRequest的Handler,执行链管理器HandlerExecutionChain
{
// handlerMappings = [
// org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping 根据xml文件中配置的beanName来匹配
// org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping !!!已经过期 -- 根据类上的@RequestMapping注解来匹配
// org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping !!!新的
// ]
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
3、获取当前请求 mappedHandler 的适配器 ha(HandlerAdapter)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 决策一个适合Handler的“Handler适配器”, 四种类型的适配器
{
// handlerAdapters = [
// org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
// org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
// !!! 从3.2为止这个过期 org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
// org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
// ]
for (HandlerAdapter ha : this.handlerAdapters) {
if (ha.supports(handler)) {
return ha;
}
}
}
4、应用《前置处理器》 --- 调用拦截器列表的 preHandle 方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) { // 调用 HandlerExecutionChain 的applyPreHandle方法,迭代调用Handler的拦截器的preHandle方法
return;
}
5、执行 HandlerAdapter
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 执行handler的方法,返回值 org.springframework.web.servlet.ModelAndView
6、应用《默认视图名称》
applyDefaultViewName(processedRequest, mv); // 如果没有设置“视图”信息,会自动应用“视图”
7、应用《后置处理器》 --- 调用拦截器列表的 postHandle 方法
mappedHandler.applyPostHandle(processedRequest, response, mv); // 调用 HandlerExecutionChain 的applyPostHandle方法 ,迭代调用Handler的拦截器的postHandle方法
} catch (Exception ex) {
dispatchException = ex;
}
8、处理返回结果
1、构建 ModelAndView 对象
没有异常,
不进行处理
存在异常
用《异常解析器》,构建异常视图 ModelAndView
for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) { // 迭代异常解析器列表
exMv = handlerExceptionResolver.resolveException(request, response, handler, ex); // 解析异常
if (exMv != null) {
break;
}
}
2、执行渲染
1、获取Local
Locale locale = this.localeResolver.resolveLocale(request); // 检查语言
response.setLocale(locale);
2、渲染
view.render(mv.getModelInternal(), request, response); // 渲染
3、应用《完成处理器》 --- 调用拦截器列表的 afterCompletion 方法
mappedHandler.triggerAfterCompletion(request, response, null);
} catch (Exception ex) {
9、应用《完成处理器》 --- 调用拦截器列表的 afterCompletion 方法
mappedHandler.triggerAfterCompletion(request, response, ex);
}
}
*/
doService(request, response); // !!!! 子类
}
catch (ServletException ex) {
failureCause = ex;
throw ex;
}
catch (IOException ex) {
failureCause = ex;
throw ex;
}
catch (Throwable ex) {
failureCause = ex;
throw new NestedServletException("Request processing failed", ex);
}