Springboot请求映射原理

springboot中的spring-boot-starter-web还是使用的spring-mvc。而spring-mvc中处理所有的请求的入口就是DispatcherServlet.

而DispatcherServlet就一定要重写doGet或者doPost,但是在springboot中的DispatcherServlet中没有这两个方法。

 

 

 而是在DispatcherServlet的父类FrameworkServlet中找到了。

 

 

 

@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	processRequest(request, response);
}


@Override
protected final void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	processRequest(request, response);
}

  看出不管是doGet还是doPost都是执行的processRequest这个方法。

processRequest方法
 1 protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3 
 4         long startTime = System.currentTimeMillis();
 5         Throwable failureCause = null;
 6 
 7         LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
 8         LocaleContext localeContext = buildLocaleContext(request);
 9 
10         RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
11         ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
12 
13         WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
14         asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
15 
16         initContextHolders(request, localeContext, requestAttributes);
17 
18         try {
19             doService(request, response);
20         }
21         catch (ServletException | IOException ex) {
22             failureCause = ex;
23             throw ex;
24         }
25         catch (Throwable ex) {
26             failureCause = ex;
27             throw new NestedServletException("Request processing failed", ex);
28         }
29 
30         finally {
31             resetContextHolders(request, previousLocaleContext, previousAttributes);
32             if (requestAttributes != null) {
33                 requestAttributes.requestCompleted();
34             }
35             logResult(request, response, failureCause, asyncManager);
36             publishRequestHandledEvent(request, response, startTime, failureCause);
37         }
38     }

主要看第19行的doService(request, response);方法,而这个方法中又调用了核心的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 {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
				mappedHandler = getHandler(processedRequest);

  通过getHandler方法拿到对应可以处理当前请求的mappedHandler;

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}

  debug之后发现会有如下几个HandlerMapping;

 

 而我们需要找到的是

RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。

 

 当有请求进来时,会循环尝试所有的HandlerMapping看是否有请求信息。

    • 如果有就找到这个请求对应的handler
    • 如果没有就是下一个 HandlerMapping

Springboot请求映射原理就是其实就是查询对应HandlerMapping进行请求处理

 

posted @ 2022-07-29 17:01  swayer  阅读(221)  评论(0编辑  收藏  举报