有人活了大半輩子還不知道servlet是啥翠肘?它在tomcat中又是怎么生活的呢?來辫秧,安排上~~
讓我們把回憶拉回到很久很久以前束倍,呃,就是 springboot 啟動的時間點盟戏,找到 ServletWebServerApplicationContext#refresh() 這個方法绪妹,走下去,是 onRefresh() 方法里的createWebServer() 方法柿究,點開它:
這里以 dispatcherServlet 的加載為例邮旷,待會就盯著她。點開getSelfInitializer()方法婶肩,在關(guān)鍵地方打個斷點:
可以看到,這里通過getServletContextInitializerBeans()方法貌夕,獲取到所有的 ServletContextInitializer進(jìn)行遍歷律歼,調(diào)用各自的 onStartup()。在遍歷到 DispatcherServletRegistrationBean的時候啡专,進(jìn)入 onStartup()方法看看:
已經(jīng)看到dispatcherServlet了险毁,感覺離成功不遠(yuǎn)啰~
點 register(description, servletContext)進(jìn)去:
再點 addRegistration()進(jìn)入,拼上最后一口氣,追到這里畔况,看關(guān)鍵代碼:
private ServletRegistration.Dynamic addServlet(String servletName, String servletClass,
Servlet servlet, Map<String,String> initParams) throws IllegalStateException {
……
// 查找context里是否有該servlet(這里的context是TomcatEmbeddedContext鲸鹦,
// servletName是 dispatcherServlet)
Wrapper wrapper = (Wrapper) context.findChild(servletName);
// 查找不到,則創(chuàng)建一個添加到context中问窃。Wrappe 封裝了servlet
if (wrapper == null) {
wrapper = context.createWrapper();
wrapper.setName(servletName);
context.addChild(wrapper);
}
………
// 繼續(xù)設(shè)置wrapper的servlet屬性
wrapper.setServletClass(servlet.getClass().getName());
wrapper.setServlet(servlet);
……
// 構(gòu)建 ApplicationServletRegistration返回
ServletRegistration.Dynamic registration =
new ApplicationServletRegistration(wrapper, context);
return registration;
}
啰啰嗦嗦了半天亥鬓,一句話概括就是:把servlet注冊到context里
到這里,已是柳暗花明域庇。我們再講講這里的 dispatcherServlet 是什么時候創(chuàng)建的嵌戈。
再回想公元前某個夜晚,我們講的springboot自動裝配原理听皿,打開:
打開DispatcherServletAutoConfiguration這個類熟呛,上圖,此時無聲勝有聲:
簡簡單單尉姨,關(guān)機落班~