In the SpringBoot source series (I) : In-depth understanding of the principle of automatic configuration, I have taken you to understand the basic annotations and processes involved in automatic configuration, but SpringBoot in what time to automatic configuration, this must start from the SpringBoot Boot process analysis.

SpringApplication.run()

SpringBoot projects usually have a main startup class, and the main startup class will have a main method. We know that the main method is the entry point for Java programs to start, so we can study the SpringBoot startup principle from this main method.

@SpringBootApplication public class DemoApplication { public static void main(String[] args) { // DemoApplication.class That is for our startup class springApplication.run (demoApplication.class, args); }}Copy the code

Heaviest SpringApplication. Run method is invoked org. Springframework. Boot. SpringApplication# run (Java. Lang. String…). Methods, this method is mainly to create context, the return type for ConfigurableApplicationContext context. The process is as follows:

  1. Start monitor
  2. Gets and starts the event listener
  3. Preparing the environment: Load various configuration files, such as Properties
  4. Creating a context
  5. Creating an object factory
  6. Refresh context
  7. Pause monitor
public ConfigurableApplicationContext run(String... Args) {// 1. Start the monitor StopWatch StopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); this.configureHeadlessProperty(); / / 2. Obtain and open the listener SpringApplicationRunListeners listeners = this. GetRunListeners (args); listeners.starting(); Collection exceptionReporters; try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = this. PrepareEnvironment (listeners, applicationArguments); this.configureIgnoreBeanInfo(environment); Banner printedBanner = this.printBanner(environment); / / 4. Create a context context = this. CreateApplicationContext (); / / 5. Create an object factory exceptionReporters = this. GetSpringFactoriesInstances (SpringBootExceptionReporter. Class, new Class[]{ConfigurableApplicationContext.class}, context); this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 6. RefreshContext (context); this.afterRefresh(context, applicationArguments); // 7. Stop the monitor stopwatch.stop (); if (this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch); } listeners.started(context); this.callRunners(context, applicationArguments); } catch (Throwable var10) { this.handleRunFailure(context, var10, exceptionReporters, listeners); throw new IllegalStateException(var10); } try { listeners.running(context); return context; } catch (Throwable var9) { this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null); throw new IllegalStateException(var9); }}Copy the code

refresh

In the above step 6, is to refresh the application context, this step is to call the org. Springframework. Context. Support. AbstractApplicationContext# refresh () method, also is the main starting process of the Spring. This.onrefresh () is an abstract method, leaving the specific context refresh to subclasses.

In the implementation class, we can find ServeltWebServerApplicationContext is one of the implementation.

public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { this.postProcessBeanFactory(beanFactory); this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); }}}Copy the code

ServeltWebServerApplicationContext

ServeltWebServerApplicationContext onRefresh method will call createWebServer method to create a Tomcat instance, and initialize the Servlet context.

protected void onRefresh() { super.onRefresh(); try { this.createWebServer(); } catch (Throwable var2) { throw new ApplicationContextException("Unable to start web server", var2); } } protected void doClose() { if (this.isActive()) { AvailabilityChangeEvent.publish(this, ReadinessState.REFUSING_TRAFFIC); } super.doClose(); } private void createWebServer() { WebServer webServer = this.webServer; ServletContext servletContext = this.getServletContext(); if (webServer == null && servletContext == null) { ServletWebServerFactory factory = this.getWebServerFactory(); this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()}); this.getBeanFactory().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle(this.webServer)); this.getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer)); } else if (servletContext ! = null) { try { this.getSelfInitializer().onStartup(servletContext); } catch (ServletException var4) { throw new ApplicationContextException("Cannot initialize servlet context", var4); } } this.initPropertySources(); }Copy the code

conclusion

If an interviewer asks you how Spring Boot Tomcat starts, you can reply:

  1. The main method of Spring Boot calls the springApplication.run () method. The run method is the entry point for starting the class. The run method registers listeners, prepares the environment, creates the context, refreshes the context, And return a type for ConfigurableApplicationContext context.
  2. Which refreshes the context will call ServletWebServerApplicationContext onRefresh () method, which will create a Tomcat through factory object, and initialize the Servlet context.