传统的springmvc容器的初始化过程:
1,通过SpringServletContainerInitializer来负责对容器启动时的相关组件的初始化,在web这个jar包下面有个meta-inf目录,下面有个services目录,下面有个javax.servlet.ServletContainerInitializer文件,里面指明了SpringServletContainerInitializer
2,到底要初始化哪些组件是通过Servlet规范中所提供的注解handlesTypes来指定的
3,在SpringServletCOntainerInitializer中,其HandlesTYpes注解则明确指定为了WebApplicationInitializer.class类型作为onStartup方法的第一个参数
4,在SpringServletContainerIntializer的onStartup方法中,则主要是完成了一些验证与组件装配的工作
5,在SpringServletCOntainerInitializer的onStartup方法中,由于某些容器并未遵循Servlet规范,导致虽然明确指定了HandlesTYpe注解的类型为webApplicationInitializer.class类型,但还是可能会存在将一些非法类型传递过来的情况,所以该方法还对传递过来的具体类型进行了细致的判断,只有符合条件的类型才会被纳入到List<webApplicationInitializer>集合中
6,当以上判断完成之后,LIst<WebApplicationInitializer>就是接下来需要进行初始化的组件了,
7,最后,通过遍历LIst<WebApplicationInitializer>列表,取出其中的每一个webApplicationInitializer对象,调用这些对象的onStartup方法,完成组件的启动初始化工作
总结一下:SpringServletContainerInitializer在整个初始化过程中,其扮演的角色实际上是委托或者是代理的角色,真正完成初始化工作的是一个个的webApplicationInitializer实现类
现代的springboot应用的容器初始化过程:
1,对于一个springboot应用来说,它并没有使用SpringServletContainerInitializer来进行容器的初始化,而是使用了TomcatStarter进行的。
2TomcatStarter存在三点因素使得它无法通过SPI机制进行初始化:它没有不带参数的构造方法,它的声明并非public,其所在jar包并没有META-INF.services目录,当然也不存在名为javax.servlet.sertvletContainerInitialezer的文件了
3,综上,TOmcatStarter并非通过SPI机制进行的查找和实例化
4,本质上,TOmcatStarter是通过spring boot框架new出来的
5,与SpringServletContainerInitializer类似,TomcatStarter在容器的初始化过程中也是扮演着一个委托或者是代理的角色,真正执行的初始化动作实际上是由它所持有的ServletContextInitializer的onStartup方法来完成的
关于传统的springmvc和现代的springboot应用组件之间的对应关系:
1,springServletContainerInitializer对应于TomcatStarter
2,webApplicationInitializer对应于ServletContextInitializer