初始化完Spring對象容器后,創建並啟動WebServer。
Tomcat獲取Server先獲取Service,把Service放入Server中后再返回。
Tomcat獲取Host先獲取Engine,獲取Engine先獲取Service和Host,將Service用來處理所有請求的引擎容器設置為Engine,將Host放入Engine這個容器的子容器集合中。
將上下文初始化器配置到【【【【【Tomcat內的】Server下的】Service的】容器Engine下的】Host的子容器中的】TomcatEmbeddedContext內的】容器初始化器TomcatStarter。其中Engine、Host、TomcatEmbeddedContext都是接口Container的實現類。
在對TomcatEmbeddedContext進行配置的時候,配置了兩個初始化器集合。先將從Sring容器中獲取的用來注冊過濾器的ServletContextInitializer集合放入TomcatStater的initializers屬性中。而TomcatStater本身就是個用來初始化容器的ServletContainerInitializer,再將其加入TomcatEmbeddedContext下用來初始化的initializers屬性中。
WebServer為TocatWebServer,實例化后立即初始化,並使其tomcat啟動。
Tomcat使其Server啟動。
Server使其Service啟動。
Service使其Engine啟動。
Engine啟動其包含的子容器,即初始化時加入的Host。啟動過程為,通過子容器構建一個接口Callable的實現類StartChild的實例。
之前將Host加入Engine的子容器集合。
然后在線程池AbstractExecutorService的submit方法中,異步執行由StartChild構建的FutureTask。
由於StartChild實現了Callable接口,所以在被線程池通過FutureTask啟動時,會調用器call()方法。此時賦值為Host的屬性child將被啟動,因為Host實現了接口Container和Lifecycle。
Host接下來又會執行它生命周期的啟動過程。
通過線程池、StartChild和FutureTask啟動Host的子容器TomcatEmbeddedContext。
之前將TomcatEmbeddedContext加入Host的子容器集合中。
TomcatEmbeddedContext開始啟動。
從屬性initializers中依次取出容器初始化器進行啟動,並傳入Tomcat的上下文ApplicationContext的ApplicationContextFacade。
第一個要啟動的就是之前放入的TomcatStater。
TomcatStarter的啟動過程就是讓其所擁有的上下文初始化器啟動起來。
而它擁有的上下文初始化器就是Spring容器中通過lambda表達式實現的ServletContextInitializer的匿名類,它的方法onStartup()將會執行ServletWebServerApplicationContext的方法selfInitialize()。
接下來就是先通過方法getServletContextInitializerBeans()從Spring容器中獲取到用來注冊過濾器的ServletContextInitializer即FilterRegistrationBean,當然也包含用來注冊其它Bean的初始化器。然后調用這些上下文初始化器的方法onStartup(),進行啟動並將過濾器添加到ApplicationContextFacade中。