web服务的规范,不得不提Servlet,Servlet指定了web应用的规范,其中定义了servlet相关的接口和filter相关的接口。
Servlet接口
filter接口
这些接口怎么用?
大致的规则是,web容器,如tomcat 执行/调用 Servlet
ServletContext接口
tomcat实现该接口的类:
这里的context的作用是什么?
用来 将 servlet 和 web服务器关联起来的吧。
ServletContainerInitializer接口
通过接口名,可以知道是 servlet容器初始化的,那么初始化什么呢?
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException;
该接口唯一的方法,入参是 ServletContext接口,难道是初始化 ServletContext吗?
看下 spring boot 2.3.12版本的 TomcatStarter 实现:
ServletContextInitializer接口好像不是 servlet规范里的接口,纯粹是 spring boot 2.3.12自己定义的接口,方便扩展。
再看下 spring web 模块的实现SpringServletContainerInitializer:
WebApplicationInitializer接口好像不是 servlet规范里的接口,纯粹是 spring web模块自己定义的接口,方便扩展。
目的都是 构建ServletContext,添加 servlet,filter,listener这些。
分析下tomcat的代码执行逻辑:
web服务再创建ApplicationContext时,会执行createWebServer方法,该方法是启动tomcat。
ServletWebServerFactory 接口用来创建 web服务器,实现类可以看下 TomcatServletWebServerFactory,
这里的代码也比较清晰,创建tomcat实例,配置连接器等。
看下prepareContext(tomcat.getHost(), initializers);
这里 准备 context,是什么context?
TomcatEmbeddedContext 是 tomcat内置的上下文,跟servletContext不是一回事。
该方法放下看,
TomcatStarter,上面描述过,是用来初始化servlet容器的。也就是 通过传入的 ServletContextInitializer 来初始化的。
这里有 servlet注册,filter注册,listener注册的 ServletContextInitializer bean,
servlet注册的 DispatcherServlet,到这里,是不是恍然大悟。
看下TomcatEmbeddedContext
开始调用 ServletContainerInitializer
到这里才实例化 servletContext, ApplicationContext,
这里的servletContext 和 下图红框里获取的是同一个 对象吗? 是的
这里 会把 servletContext 塞给 ServletWebServerApplicationContext。
通过以上的分析,大致了解了 servlet /filter 用再哪里,再哪里注册,以及web服务启动过程。
如何响应请求,执行的逻辑是什么?