Spring WebMVC

695
0
0
最后修改于

webmvc 是一套基于 servlet 的 MVC 框架,较为全面,但是随着时间推进,前后端分离称为主流。
MVC 中为视图服务的能力就不那么重要了。

但是仍然使用相同的处理模型。

try {  
	val mv: ModelAndView? = null
	val dispatchException: Exception? = null
    try {  
	   val processedRequest = checkMultipart(request)
       val multipartRequestParsed = processedRequest != request
  
       // 从 dispatcherServlet 持有的所有 handler 中,拿到一个匹配当前请求的handler
       val mappedHandler :Handler? = getHandler(processedRequest)
       if (mappedHandler == null) {  
          noHandlerFound(processedRequest, response);
          return;  
       }  
	  // 拿到一个handler 对应的 adapter,这里很奇怪,为什么不直接保留经过 adapter 包装的 handler,也就是只持有 adapter
	  // 此处有可能找不到adapter,就会抛出异常
	  // 仔细考虑一遍,查看后面的代码,
	  // 不难发现,adapter 是少数几种,而handler 是多数
	// adapter 并不持有handler,而是每次调用
		val ha = getHandlerAdapter(mappedHandler.getHandler())       
       // 处理 lastmodified
       // 对于 get/head 方法
       val modified = processLastModified(request, ha, mappedHandler.getHandler())
       if(!modified) {
	       return
       }
       
	  // interceptor 前置处理,可能被拦截
       if (!mappedHandler.applyPreHandle(processedRequest, response)) {  
          return
       }  
  
       // 调用handler,得到modelAndView
       // 通过 requestMapping 可能直接返回 JavaObject,然后通过 adapter转为 modelAndView(最后渲染,搭配 Jackson等序列化工具,转为 json)
       mv = ha.handle(processedRequest, response, mappedHandler.getHandler())
       if (asyncManager.isConcurrentHandlingStarted()) {  
          return
       }  
       
       applyDefaultViewName(processedRequest, mv)
       
	  // interceptor 后置处理
       mappedHandler.applyPostHandle(processedRequest, response, mv); 
    } catch (Exception ex) {  
       dispatchException = ex
     }
} catch (Throwable err) {  
       // As of 4.3, we're processing Errors thrown from handler methods as well,  
       // making them available for @ExceptionHandler methods and other scenarios.       dispatchException = new NestedServletException("Handler dispatch failed", err);  
    }  
    processDispatchResult(
	    processedRequest,
		response, 
		mappedHandler,
	    mv,
	    dispatchException
    )
}

MVC 如何拿到 controller / requestMapping?

每个 handlerMapping 在初始化之后,从 bean factory 中扫描符合条件的 Bean 中的方法作为 handler

比如 requestMapping,本身用的是 HandlerMethodMapping,对所有的 Bean,判断是否带有 Controller 注解,如果是,就检测其内部可以作为 HandlerMethod 的方法 (带有 @requsetMapping 或者 @httpExchange) 作为 handler

而 routeFunction 则是扫描 RouteFunction.class 的 bean,将其中的 route 加入 handler 中

MVC 如何构成 handler 的链,进行筛选?