深入源码了解Tomcat加载servlet的过程

有人活了大半辈子还不知道servlet是啥?它在tomcat中又是怎么生活的呢?来,安排上~~

让我们把回忆拉回到很久很久以前,呃,就是 springboot 启动的时间点,找到 ServletWebServerApplicationContext#refresh() 这个方法,走下去,是 onRefresh() 方法里的createWebServer() 方法,点开它:

getSelfInitializer.png

这里以 dispatcherServlet 的加载为例,待会就盯着她。点开getSelfInitializer()方法,在关键地方打个断点:

selfInitialize.png

可以看到,这里通过getServletContextInitializerBeans()方法,获取到所有的 ServletContextInitializer进行遍历,调用各自的 onStartup()。在遍历到 DispatcherServletRegistrationBean的时候,进入 onStartup()方法看看:

onStartup.png

已经看到dispatcherServlet了,感觉离成功不远啰~

点 register(description, servletContext)进去:

register.png

再点 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自动装配原理,打开:

dispatcherServlet自动装配.png

打开DispatcherServletAutoConfiguration这个类,上图,此时无声胜有声:

dispatcherServlet加载.png
dispatcherServletRegistration加载.png

简简单单,关机落班~

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容