天天看點

Spring-web源碼解析之Initializer

基于4.1.7.RELEASE

Spring-WebApplicationInitializer

AbstractContextLoaderInitializer / AbstractDispatcherServletInitializer / AbstractAnnotationConfigDispatcherServletInitializer

後3個類都是實作了WebApplicationInitializer接口,WebApplicationInitializer接口主要的作用是提供在Servlet 3.0+環境中對于ServletContext的可程式設計實作,可以跟web.xml混合使用,該接口的實作類會被SpringServletContainerInitializer自動調用,而SpringServletContainerInitializer則會被任意3.0+的Servlet自動啟用,可以使用@Order注解來定義WebApplicationInitializer的執行順序。

值得注意的一點是在tomcat的7.0.14(包含)以下版本時, tomcat會把url :“/”跟DefaultServlet綁定在一起且無法重寫綁定關系。

需要注意的方法:

而在AbstractDispatcherServletInitializer類中,onStartup則被重寫,調用了本類的registerDispatcherServlet方法,注冊了一個預設名字為dispatcher的DispatcherServlet,并且對Servlet進行了一些初始化工作。

由代碼中可以看出,在注冊完dispatchServlet之後,設定啟動優先級為1表明該Servlet随容器啟動而初始化,添加Servlet的URL mapping即web.xml中的url-pattern選項,注冊Servlet的filters并且調用了customizeRegistration方法來實作自定義配置ServletContext。其中

getServletName(), customizeRegistration() 可由實作類自己決定是否重寫

createServletApplicationContext(),createRootApplicationContext()(繼承自AbstractContextLoaderInitializer),getServletMappings()子類必須實作

有一個有意思的現象是在registerServletFilter中添加Filter時

這表明,同一個名稱的filter最多隻能注冊100個。

由于AbstractAnnotationConfigDispatcherServletInitializer繼承了AbstractDispatcherServletInitializer,是以它滿足了上面要求的createServletApplicationContext(),createRootApplicationContext()兩個方法實作,而由于它是一個抽象類,getServletMappings()則被交給它的子類去實作。這兩個方法的實作大同小異

如上所示,其不同在意擷取configClasses的不同之處,一個是擷取用于Servlet Application Context的配置,另一個是用于root Application Context的配置,無論是用在哪裡,都是由其子類通過注解@Configuration和@Component來辨別的。

繼續閱讀