Beginner’s mind

Why do you want to learn Spring Boot source code?

The first point is that THE purpose of my study is utilitarian, which is for the better development of my career. In short, improve your chances of finding a good company the next time you change jobs; Be able to ask for a higher salary.

Second point: through learning source code, improve their engineering thinking, coding skills and so on coding strength. Inspire to write elegant code.

Number three: Spring Boot is the most commonly used framework in the Java space on a daily basis. Now I just know how to use it, but I don’t know anything about its internal logic.

The “Learn More about Spring Boot” program takes the form of output forcing input. Due to my limited level, this series is purely study notes. In the course of learning, I will refer to a wide range of online materials, including but not limited to nuggets, CSDN, Blog Park, MOOCs, Baidu, Google, etc.

An overview of the startup process

The entire Spring Boot container starts in three major steps:

Graph LR A(frame initialization) --> B(frame start) --> C(automatic assembly)

Let’s break it down and learn step by step.

Framework initialization

The standard boot classes are as follows:

@SpringBootApplication
public class InDepthSpringBootApplication {
    public static void main(String[] args) { SpringApplication.run(InDepthSpringBootApplication.class, args); }}Copy the code

You can see that SpringApplication#run is called, so click to continue.

public static ConfigurableApplicationContext run(Class
        primarySource, String... args) {
        return run(newClass<? >[] { primarySource }, args); }// Notice that we are entering the new SpringApplication() constructor
public static ConfigurableApplicationContext run(Class
       [] primarySources, String[] args) {
        return new SpringApplication(primarySources).run(args);
    }
 
public SpringApplication(Class
       ... primarySources) {
        this(null, primarySources);
    }
 
public SpringApplication(ResourceLoader resourceLoader, Class
       ... primarySources) {
  // Resource loader, null
        this.resourceLoader = resourceLoader;
  // The main class, which is usually the startup class
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
  // Environmental monitoring. Determine whether MVC or WebFlux is started
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
  // Set the system initializer
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
  // Set the listener
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  // Configure the class where main resides
        this.mainApplicationClass = deduceMainApplicationClass();
    }
 
Copy the code

The above methods are in the SpringApplication class, in order of call.

In SpringApplication (ResourceLoader ResourceLoader, Class
… PrimarySources) is the framework initialization logic.

The two methods we need to focus on here are setting the system initializer and setting the listener. We’ll learn more about that later.

Framework starts

The SpringApplication class is created, and the next step is to call the run method, which is the core startup process:

public ConfigurableApplicationContext run(String... args) {
  / / timer
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
  // Set parameters
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
  // Configure Headless mode (no monitor, no keyboard, etc.)
        configureHeadlessProperty();
  // Send the start event
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
      // Configure the environment and send the environment configuration completion event
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
            configureIgnoreBeanInfo(environment);
      / / print the banner
            Banner printedBanner = printBanner(environment);
      // Create the context
            context = createApplicationContext();
      // Initialize the exception report
            exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
      // contextPrepared (contextPrepared, Sources loaded to context, contextLoaded, etc.)
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      // Refresh context (instantiate Bean, etc.)
            refreshContext(context);
      // Work after refresh
            afterRefresh(context, applicationArguments);
      // Stop the timer
            stopWatch.stop();
      / / log
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
            }
      // Send the started event
            listeners.started(context);
      // Execute the Runner class
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
      // The startup fails and the handling is abnormal
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }
 
        try {
      // Send the running event
            listeners.running(context);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }
Copy the code

Above is the core method of Spring Boot Boot, with almost every line a method and hundreds or thousands of lines of complex code hidden behind it. We still need to learn slowly.

Attached is a frame startup picture:

Automatically.

Autowiring is actually included in the framework startup. Just because this is a very, very, very important feature and extension point of Spring Boot, it remains a separate process.

The autowire logic is mainly in the refresh context method.

The automatic assembly itself has fewer steps:

conclusion

This article, mainly from the global perspective, takes a rough look at the Spring Boot Boot process.

It’s important to understand the rough process of starting Spring Boot, but we’ll learn the details later.