Tomcat加載servlet過程
有人活了大半輩子還不知道servlet是啥?它在tomcat中又是怎麼生活的呢?來,安排上~~
讓我們把回憶拉回到很久很久以前,呃,就是 springboot 啓動的時間點,找到 ServletWebServerApplicationContext#refresh() 這個方法,走下去,是 onRefresh() 方法裏的createWebServer() 方法,點開它:
這裏以 dispatcherServlet 的加載為例,待會就盯着她。點開getSelfInitializer()方法,在關鍵地方打個斷點:
可以看到,這裏通過getServletContextInitializerBeans()方法,獲取到所有的 ServletContextInitializer進行遍歷,調用各自的 onStartup()。在遍歷到 DispatcherServletRegistrationBean的時候,進入 onStartup()方法看看:
已經看到dispatcherServlet了,感覺離成功不遠囉~
點 register(description, servletContext)進去:
再點 addRegistration()進入,拼上最後一口氣,追到這裏,看關鍵代碼:
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);
// 查找不到,則創建一個添加到context中。Wrappe 封裝了servlet
if (wrapper == null) {
wrapper = context.createWrapper();
wrapper.setName(servletName);
context.addChild(wrapper);
}
………
// 繼續設置wrapper的servlet屬性
wrapper.setServletClass(servlet.getClass().getName());
wrapper.setServlet(servlet);
……
// 構建 ApplicationServletRegistration返回
ServletRegistration.Dynamic registration =
new ApplicationServletRegistration(wrapper, context);
return registration;
}
囉囉嗦嗦了半天,一句話概括就是:把servlet註冊到context裏
到這裏,已是柳暗花明。我們再講講這裏的 dispatcherServlet 是什麼時候創建的。
再回想公元前某個夜晚,我們講的springboot自動裝配原理,打開:
打開DispatcherServletAutoConfiguration這個類,上圖,此時無聲勝有聲:
簡簡單單,關機落班~