博客 / 詳情

返回

深入源碼瞭解Tomcat加載servlet的過程

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這個類,上圖,此時無聲勝有聲:

簡簡單單,關機落班~
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.