基于版本spring boot 2.1.5.RELEASE
spring boot 启动时会调用SpringApplication#run(String... args)方法,一切都从这里开始。
整体流程
1. ApplicationContext创建
spring boot会调用org.springframework.boot.SpringApplication#createApplicationContext方法,根据webApplicationType值创建ApplicationContext。
一般web环境都是创建AnnotationConfigServletWebServerApplicationContext,也只有当前应用为网络应用时才会启动内嵌的 Servlet 容器。(Servlet 容器创建及启动的实现在ServletWebServerApplicationContext中,而AnnotationConfigServletWebServerApplicationContext继承了该类)。
2. 创建Servlet 容器
run方法中,spring boot会通过refreshContext()方法调用ApplicationContext的refresh()方法(该方法由ApplicationContext实例的父类AbstractApplicationContext提供实现,是模板方法的应用,里面定义了ApplicationContext的启动流程)。
refresh()方法定义的流程
public void refresh() {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
... ...
复制代码
子类ServletWebServerApplicationContext 重写的onRefresh()方法被调用。
这个方法里通过createWebServer()创建了 Servlet容器(默认为 Tomcat),并添加 IoC 容器中的 Servlet、Filter 和 EventListener至 Servlet上下文。
3. 启动容器
子类ServletWebServerApplicationContext 重写的finishRefresh()方法被调用。
这个方法里通过startWebServer()调用WebServer#start方法启动创建的容器。
createWebServer 方法
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#createWebServer
以tomcat容器为例:
private void createWebServer() {
WebServer webServer = this.webServer;
// 获取被加载都ioc容器中的TomcatServletWebServerFactory
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = getWebServerFactory();
// 生成一个TomcatWebServer实例
this.webServer = factory.getWebServer(getSelfInitializer());
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context",
ex);
}
}
initPropertySources();
}
复制代码
spring boot在org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServer
给tomcat设置了相关的配置。
其中org.apache.catalina.connector的实例化给Tomcat引入了默认配置。
源码路径:
- org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServer
- Connector connector = new Connector(this.protocol);
- Class<?> clazz = Class.forName(protocolHandlerClassName);
- org.apache.coyote.http11.Http11NioProtocol
- org.apache.coyote.AbstractProtocol
- org.apache.coyote.AbstractProtocol#endpoint默认配置保存在这个类中。
maxThreads: 用于接收和处理client端请求的最大线程数,默认200
acceptCount: tomcat 线程池所有线程忙碌时,等待队列的最长长度。默认100
connectionTimeout:每个http请求的读取超时时间。默认2000ms
作者:stormbuf
链接:https://juejin.cn/post/6997773261807288357
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。