源码解析:spring boot 创建内嵌Tomcat容器并启动

基于版本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()方法调用ApplicationContextrefresh()方法(该方法由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();
      }

     ... ... 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

子类ServletWebServerApplicationContext 重写的onRefresh()方法被调用。

这个方法里通过createWebServer()创建了 Servlet容器(默认为 Tomcat),并添加 IoC 容器中的 ServletFilter EventListenerServlet上下文。

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();
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

spring boot在org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServer

给tomcat设置了相关的配置。

其中org.apache.catalina.connector的实例化给Tomcat引入了默认配置。

源码路径:

  1. org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServer

  2. Connector connector = new Connector(this.protocol);

  3. Class<?> clazz = Class.forName(protocolHandlerClassName);

  4. org.apache.coyote.http11.Http11NioProtocol

  5. org.apache.coyote.AbstractProtocol

  6. org.apache.coyote.AbstractProtocol#endpoint默认配置保存在这个类中。

maxThreads: 用于接收和处理client端请求的最大线程数,默认200

acceptCount: tomcat 线程池所有线程忙碌时,等待队列的最长长度。默认100

connectionTimeout:每个http请求的读取超时时间。默认2000ms

Last Updated: