SpringMVC源碼分析-DispatcherServlet實例化幹了些什麼

上一篇:SpringMVC啓動與Spring啓動差別分析java

閱讀這篇文章以前,請先按照模擬SpringBoot編寫一個嵌套Tomcat的工具類(方便調試)完成環境的搭建web

思考

在開始看源碼以前先作一下思考,好比:spring

1.SpringMVC既然能從Tomcat哪裏接收請求,那麼SpringMVC必定是提供了一個Servlet的,並且是由這個Servlet完成全部的請求和響應。tomcat

2.既然這個Servlet能夠提供很是多的功能,並且和Spring相關,那麼它應該持有某一種Spring的XxxApplicationContextmvc

3.有了Context,SpringMVC是否是還提供了很是多默認的類去實現複雜的功能,好比參數解析、參數綁定、返回值解析、視圖解析等等app

 

有了上面的問題,下面帶着問題去一個個驗證。。。工具

經過官方文檔或者百度或者本身開發經驗應該知道有DispatcherServlet這個類。。。。是的,它就是SpringMVC傳世紀的類,由它打通tomcat和Spring容器,並讓咱們的Bean擁有Spring容器豐富多彩功能的權利。源碼分析

類結構圖

那麼先分析DispacherServlet的類結構圖spa

能夠看到它是Servlet,ApplicationContextAware,EnvironmentAware的子類,那麼應該有一下幾個特性:.net

1.能被Tomcat識別與調用,調用的時候會先調用init方法,再調用doXxx方法

2.能夠在DispatcherServlet中輕鬆的獲取Context和Environment對象,並且由Spring完成它的實例化(尚待證明,等後面看SpringBoot源碼來確認)

源碼分析

套路分析:類被實例化以前會先加載,類加載的時候會執行類變量初始化、靜態塊。因此先看看DispatcherServlet及其父類是否有靜態塊要執行。。。答案是有

DispatcherServlet的靜態塊

static {
		// Load default strategy implementations from properties file.
		// This is currently strictly internal and not meant to be customized
		// by application developers.
		/**
		 * 從DispatcherServlet.properties(此文件在webmvc工程下)當中加載默認的strategy(有道翻譯:策略)
		 * SpringMVC官方說:這些類是核心的東西,不容許讓普通開發者進行自定義,固然以爲本身牛逼也是能夠上
		 */
		try {
			/**
			 * 將在DispatcherServlet.class路徑下的DispatcherServlet.properties文件包裝到一個ClassPathResource當中
			 */
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
			/**
			 * 從DispatcherServlet.properties文件中把配置信息加載爲Properties對象,裏面包含了以下幾大部分
			 * LocaleResolver/ThemeResolver/HandlerMapping/HandlerAdapter/HandlerExceptionResolver/RequestToViewNameTranslator/
			 * ViewResolver/FlashMapManager
			 */
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
		}
	}

簡單說明一下:

DispatcherServlet.properties當中配置的類都是很是重要的,不要動它們,它們最終都是有Spring完成實例化,因此咱們能夠寫XxxPostProcessor對它們的實例化進行干預,實現一些自定義的功能。

看看配置文件裏面的內容,時刻牢記一點,它們很重要,後面DEBUG看到的類幾乎都是經過它們帶出來的,由於實例化它們的時候,由會默認弄出不少resolver出來。而後根據不一樣參數去匹配不一樣的resolver完成入參、出參、映射等等功能。

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
	org.springframework.web.servlet.function.support.RouterFunctionMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
	org.springframework.web.servlet.function.support.HandlerFunctionAdapter


org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

另外還設置了不少類變量的默認值,在此不去分析每個變量的做用,工做量太龐大了。

DispatcherSerlvet實例化

構造方法的執行與成員變量初始化

構造方法

public DispatcherServlet(WebApplicationContext webApplicationContext) {
		super(webApplicationContext);
		setDispatchOptionsRequest(true);
	}

將Spring的上下文與DispatcherServlet關聯起來,而且將dispatchOptionsRequest設置爲true,它的做用是開啓Servlet是否能夠處理http的options

 

下一篇:SpringMVC源碼分析-DispatcherServlet的Init

相關文章
相關標籤/搜索