Spring 核心原理 5 分鐘: spring 處理請求的主流程是怎樣的?

Spring 中整個處理請求的主流程是啥?經常進行 spring 開發,大家知道攔截器,過濾器,還有具體的 Controller 處理。大體的順序也能理清楚。但是不看源碼總覺得不踏實。那麼 spring 到底是如何處理的呢?事實上,非常簡單。用不了 5 分鐘,你就達到給別人講解程度。

public class DispatcherServlet extends FrameworkServlet {

  private List<HandlerAdapter> handlerAdapters;
  
  private List<HandlerMapping> handlerMappings;
  
	private void initHandlerAdapters(ApplicationContext context) {
		this.handlerAdapters = null;

		if (this.detectAllHandlerAdapters) {
			// 從 context 查
			Map<String, HandlerAdapter> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerAdapters = new ArrayList<>(matchingBeans.values());
				// We keep HandlerAdapters in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerAdapters);
			}
		}
		else {
			try {
        // 從 context 配置中找
				HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
				this.handlerAdapters = Collections.singletonList(ha);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerAdapter later.
			}
		}

		// 默認的
		if (this.handlerAdapters == null) {
			this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
		}
	}  
  
	private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;

		if (this.detectAllHandlerMappings) {
			// 從 context 查
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerMappings = new ArrayList<>(matchingBeans.values());
				// We keep HandlerMappings in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}
		else {
			try {
        // 從 context 配置中找
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerMapping later.
			}
		}

		// 默認的
		if (this.handlerMappings == null) {
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
		}
	}  
  
  
	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {

		// Make framework objects available to handlers and view objects.
		request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
		request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
		request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
		request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());


	  doDispatch(request, response);

	}
  
	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
		HttpServletRequest processedRequest = request;

    try {
      // 從 handlerMappings 找到 processedRequest 對應的 HandlerExecutionChain
      HandlerExecutionChain mappedHandler = getHandler(processedRequest);

      // 調用 mappedHandler 中每個攔截器的 PreHandler 方法。如果某個攔截器返回 false,請求處理就此完成。
      if (!mappedHandler.applyPreHandle(processedRequest, response)) {
        return;
      }

      // 從 handlerAdapters 根據 mappedHandler 找到對應的 HandlerAdapter
      HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

      // 調用 HandlerAdapter 的 handler 方法處理請求
      mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

      // 生成 ModelAndView
      applyDefaultViewName(processedRequest, mv);

      ModelAndView mv = null;

      // 調用 mappedHandler 中每個攔截器的 PostHandler 方法。
      mappedHandler.applyPostHandle(processedRequest, response, mv);
    } catch (Exception var20) {
    } catch (Throwable var21) {          
    }
    // 調用 mappedHandler 中每個攔截器的 triggerAfterCompletion 方法。
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
	}
  
	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;
	}
  
	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		if (this.handlerAdapters != null) {
			for (HandlerAdapter adapter : this.handlerAdapters) {
				if (adapter.supports(handler)) {
					return adapter;
				}
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}
  
	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable Exception exception) throws Exception {

		// 生成 ModelAndView
		if (mv != null && !mv.wasCleared()) {
			render(mv, request, response);
		}

		if (mappedHandler != null) {
			mappedHandler.triggerAfterCompletion(request, response, null);
		}
	}  

	protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
		View view;
		String viewName = mv.getViewName();
		if (viewName != null) {
			// 優先使用 viewName
			view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
		}
		else {
			// 其次 View
			view = mv.getView();
		}
    
		if (mv.getStatus() != null) {
			response.setStatus(mv.getStatus().value());
		}
		view.render(mv.getModelInternal(), request, response);
	}  
}

處理器相關

    public class HandlerExecutionChain {
      
    	private final Object handler;
    
    	@Nullable
    	private HandlerInterceptor[] interceptors;
    
    	@Nullable
    	private List<HandlerInterceptor> interceptorList;
    
    	private int interceptorIndex = -1;
      
      // 調用每個攔截器的 PreHandler 方法:
      // 1. 如果返回 true,繼續下一個攔截器。
      // 2. 如果返回 false,調用已調用 preHandler 方法的攔截器的 afterCompletion,請求處理就此完成。
    	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    		HandlerInterceptor[] interceptors = getInterceptors();
    		if (!ObjectUtils.isEmpty(interceptors)) {
    			for (int i = 0; i < interceptors.length; i++) {
    				HandlerInterceptor interceptor = interceptors[i];
    				if (!interceptor.preHandle(request, response, this.handler)) {
    					triggerAfterCompletion(request, response, null);
    					return false;
    				}
    				this.interceptorIndex = i;
    			}
    		}
    		return true;
    	}
      
    	// 調用每個攔截器的 PostHandler 方法。
    	void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
    			throws Exception {
    
    		HandlerInterceptor[] interceptors = getInterceptors();
    		if (!ObjectUtils.isEmpty(interceptors)) {
    			for (int i = interceptors.length - 1; i >= 0; i--) {
    				HandlerInterceptor interceptor = interceptors[i];
    				interceptor.postHandle(request, response, this.handler, mv);
    			}
    		}
    	}
      
    	void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
    			throws Exception {
    
    		HandlerInterceptor[] interceptors = getInterceptors();
    		if (!ObjectUtils.isEmpty(interceptors)) {
    			for (int i = this.interceptorIndex; i >= 0; i--) {
    				HandlerInterceptor interceptor = interceptors[i];
    				try {
    					interceptor.afterCompletion(request, response, this.handler, ex);
    				}
    				catch (Throwable ex2) {
    					logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
    				}
    			}
    		}
    	}  
    }	

總結

整個處理流程

  1. 初始化 handlerAdapters 和 handlerMappings
  2. 根據 mappedHandler 從 handlerMappings 找到 mappedHandler
  3. 調用 mappedHandler 中每個攔截器的 PreHandler 方法。如果某個攔截器返回 false,請求處理就此完成。
  4. 調用 HandlerAdapter 的 handler 方法處理請求
  5. 生成 View
  6. 調用 mappedHandler 中每個攔截器的 PostHandler 方法
  7. 調用 mappedHandler 中每個攔截器的 triggerAfterCompletion 方法(即使有異常,該方法也確保執行)

所以整個處理流程的核心是 HandlerAdapter 的 handler 方法。關於 HandlerAdapter 的 handler 下篇文章詳述。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章