大家在使用spring boot的時候,是不是也比較好奇爲什麼我們的啓動類直接繼承SpringBootServletInitializer即可,它爲什麼能把整個應用給啓動起來呢?
一、ServletContainerInitializer
1、Servlet容器啓動會掃描,當前應用裏面每一個jar包的ServletContainerInitializer的實現
2、實現了ServletContainerInitializer接口的實現類,必須在jar包的META-INF/services/javax.servlet.ServletContainerInitializer文件裏面進行聲明,聲明的內容就是實現ServletContainerInitializer接口的全類名
3、使用SPI機制,然後進行反射實例化。
二、@HandlesTypes標籤的作用
1、@HandlesTypes標籤用在實現ServletContainerInitializer接口的類上面,比如:
@HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer
2、通過HandlesTypes可以將我們感興趣的一些類注入到ServletContainerInitializer的onStartup方法的第一個入參裏面:
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException;
3、當容器啓動的時候,我們就可以通過拿到Set<Class<?>> c裏面我們感興趣的類,然後做一些初始化的工作
三、SpringBootServletInitializer分析
1、SpringBootServletInitializer實現了WebApplicationInitializer接口
2、WebApplicationInitializer接口通過HandlesTypes註冊到SpringServletContainerInitializer
3、SpringServletContainerInitializer實現了ServletContainerInitializer接口
4、spring-web-4.3.22.RELEASE.jar裏面的META-INF\services\javax.servlet.ServletContainerInitializer文件內容註冊了SpringServletContainerInitializer的全路徑:
org.springframework.web.SpringServletContainerInitializer
5、當Tomcat啓動時候,會找到SpringServletContainerInitializer,然後再找到SpringBootServletInitializer,從而把spring容器給啓動起來