1. spring mvc 9大组件
spring mvc 9大组件
Spring mvc核心类----- DispatcherServlet.class
包含9大组件
@Nullable private MultipartResolver multipartResolver; @Nullable private LocaleResolver localeResolver; @Nullable private ThemeResolver themeResolver; @Nullable private List<HandlerMapping> handlerMappings; @Nullable private List<HandlerAdapter> handlerAdapters; @Nullable private List<HandlerExceptionResolver> handlerExceptionResolvers; @Nullable private RequestToViewNameTranslator viewNameTranslator; @Nullable private FlashMapManager flashMapManager; @Nullable private List<ViewResolver> viewResolvers;
初始化操作,初始化9大组件
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
基本是初始化都是一致的。在启动的时候将xml配置的组件初始化到DispatcherServlet中。在请求调用的时候进行使用。
handlerMappings
实现Controller的3中方式
1. 实现Controller接口
2. 实现HttpRequestHandler接口
3. 不实现任何接口,@Controller
2. springmvc流程总结
普通servlet流程
spring mvc流程
doDispatcher方法,红色的是核心方法,紫红时最核心的执行
源码注释:
//------------------------------------------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 {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
//判断是否是文件上传请请求,根据contentType判断,如果是,则会对request请求做一些处理
processedRequest = this.checkMultipart(request);
//如果processedRequest和最开始的request不一样,就认为是文件请求,multipartRequestParsed=true
multipartRequestParsed = processedRequest != request;
//根据请求获取MappingHandler,根据请求获取一个最有的MappingHandler,并包装成HandlerExecutionChain对象,同时也需要将拦截器放入到HandlerExecutionChain对象
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
//根据handler获取对应的适配器HandlerAdapter,循环HandlerAdapter适配器,找到能处理的Handler,返回最好的HandlerAdapter
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//适配器执行请求的控制器(Controller)中的方法
//handleInternal-----invokeHandlerMethod-----invokeForRequest-----getMethodArgumentValues(获取请求中的参数的具体值)---执行doInvoke()(根据获取的值执行具体的方法)
//方法执行完毕的返回值,都会放在ModeAndView对象中
//Model ModelMap Map相当于时BindingAwareModelMap
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//判断是否mv返回视图名称,如果没有则设置默认视图名称
this.applyDefaultViewName(processedRequest, mv);
//执行拦截器的postHandle
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
//将返回的视图名称做处理,渲染页面,包装异常等
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
//执行拦截器的After方法
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
//释放资源
this.cleanupMultipart(processedRequest);
}
}
}