Spring源码阅读 - MVC

MVC

① 初始化阶段:

② 运行-Dispatcher阶段:

③ 运行-ViewResolver阶段:

PS :

DispatcherServlet:

  1. onRefresh()方法,触发额外组件的初始化(MVC 9大组件)
// MVC 1 : onRefresh方法负责注册额外的初始化组件
DispatcherServlet#onRefresh(ApplicationContext context):
	initStrategies(context);

// MVC 1 : 初始化MVC 9大组件
protected void initStrategies(ApplicationContext context) {
	//多文件上传的组件
	initMultipartResolver(context);
	//初始化本地语言环境
	initLocaleResolver(context);
	//初始化模板处理器
	initThemeResolver(context);
	//handlerMapping
	initHandlerMappings(context);
	//初始化参数适配器
	initHandlerAdapters(context);
	//初始化异常拦截器
	initHandlerExceptionResolvers(context);
	//初始化视图预处理器
	initRequestToViewNameTranslator(context);
	//初始化视图转换器
	initViewResolvers(context);
	//FlashMap管理器(用于重定向过程中保留参数)
	initFlashMapManager(context);
}
  1. doService()方法,运行时入口
// MVC :运行时入口。
DispatcherServlet#doService():
    doDispatch()
        
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // MVC 2:获取到请求对应的处理器链(HandlerExecutionChain 封装了 controllerHandler + interceptors)
	mappedHandler = getHandler(processedRequest);

	// MVC 3. 用对应的HandlerAdapter获取HandlerMapping
	HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
    // A. 拦截器前置拦截方法(若前置方法存在返回值为fasle,则中止该请求)
	if (!mappedHandler.applyPreHandle(processedRequest, response)) {
		return;
	}

	// MVC 4:Actually invoke the handler,返回结果视图对象
	mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

	if (asyncManager.isConcurrentHandlingStarted()) {
		return;
	}

	// 设置默认的viewname(当mv不含有view对象时)
	applyDefaultViewName(processedRequest, mv);

	// B. 拦截器后置拦截方法
	mappedHandler.applyPostHandle(processedRequest, response, mv);
   
    // MVC 5:结果视图对象的处理
	processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
  1. HandlerAdapter.handle(),主业务调用逻辑
AbstractHandlerMethodAdapter#handle():
    // MVC 4:Actually invoke the handler,返回结果视图对象
	return handleInternal(request, response, (HandlerMethod) handler);

RequestMappingHandlerAdapter#handleInternal():
	// MVC 5:反射执行method, 获得modelAndView
	mav = invokeHandlerMethod(request, response, handlerMethod);

RequestMappingHandlerAdapter#invokeHandlerMethod():
	// MVC 5:反射执行method, 获得modelAndView
	invocableMethod.invokeAndHandle(webRequest, mavContainer);

ServletInvocableHandlerMethod#invokeAndHandle():
	// MVC 5:反射执行method, 获得modelAndView
	Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);

// InvocableHandlerMethod#invokeForRequest():
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
		// MVC : 完成参数绑定
		Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
					"' with arguments " + Arrays.toString(args));
		}
		// MVC : 反射调用方法
		Object returnValue = doInvoke(args);
		if (logger.isTraceEnabled()) {
			logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
					"] returned [" + returnValue + "]");
		}
		return returnValue;
	}
  1. ModelAndView视图渲染及响应
DispatcherServlet#processDispatchResult():
	// MVC : 如果出现异常,则由异常处理器处理异常并获得对应的MV
	mv = processHandlerException(request, response, handler, exception);
	// MVC 6 : 视图渲染并输出
	render(mv, request, response);

DispatcherServlet#render():
	// 当mv中不存在view对象时,会在handler之后被设置默认的viewName.
	// MVC : 如果viewName存在,则通过viewName解析获取到view对象
	view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
	// MVC 7 : 视图通过response渲染输出
	view.render(mv.getModelInternal(), request, response);

// AbstractView#render():
public void render(@Nullable Map<String, ?> model, HttpServletRequest request,
		HttpServletResponse response) throws Exception {
    
	if (logger.isTraceEnabled()) {
		logger.trace("Rendering view with name '" + this.beanName + "' with model " + model +
			" and static attributes " + this.staticAttributes);
	}

	// 将所有需要输出的Model(数据项)合并到一起
	Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);

	// 设置一些reponse header
	prepareResponse(request, response);

	// MVC :正式输出
	renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}
posted @ 2021-01-29 19:53  祁奇  阅读(39)  评论(0编辑  收藏  举报