Starting with this article, open a new pit and read the source code for SpringBoot.

Let’s start with the entry method.

Entry method

The entry method is springApplication.run ().

The following source code interpretation is based on a very simple SpringBoot project as an example, the following is the only Java file in the project, that is, the boot class:

package com.github.jwenjian.learning.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootLearningApplication {

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

Today’s source code analysis from SpringApplication. Run (SpringbootLearningApplication. Class, args); Start:

This method is simple, a static Helper method that builds a SpringApplication instance (line 1309) and calls its run method.

Build the SpringApplication instance

The method parameters

  • ResoureLoaer, passed null
  • Class… , is passed in an array containing only the classes of the entry class

Methods to perform

  1. Line 279: Assigns the passed resourceLoader to the instance’s property

There’s nothing to be said for this step, but when it’s done, it’s null, right

  1. Line 280: Checks the incoming class array to make sure it is not null

In general, the class array is never null, but because the constructor is public, you can’t rule out programs that create instances by calling the constructor directly instead of using the entry method, so a layer of checksum protection is required

  1. Line 281: Converts the passed class array into a set and assigns it to the instance’s property

In general, this class array contains only one element, the class of the entry class.

  1. Line 282: Detects the type of the current application and assigns the result to the instance’s properties

WebApplicationType is an enumerated class with three instances: NONE, SERVLET, and REACTIVE.

The way to detect the current application type is to detect the presence of a specific class in the classpath. In a nutshell:

  • If there is a WebFlux related class (DispatcherHandler) and no WebMVC related class (DispatherServlet) and no JERSEY related class (ServletContainer), Return the REACTIVE

  • If there is no related to the Servlet class (Servlet and ConfigurableWebApplicationContext), return NONE

  • If none of the above is satisfied, return the SERVLET

  1. Line 283: gets and instantiatesBootstraperClass, which is then assigned to the instance’s property

Here said the getSpringFactoriesInstances method, emphatically for the next two lines of code is also used this method to retrieve and instantiate related classes.

This method takes a class object (interface class) and obtains and instantiates instances of each class type as follows:

  • Gets the full class name of the interface class object passed in

  • Get a list of implementation class names that need to be instantiated based on the class name of the interface object.

    • In some SpringBoot jars, there is a meta-INF/Spring. factories file that defines key-value pairs for interface full class names = implementing a list of class full class names

    • The program reads all the meta-INF/Spring.Factories files and stores the key-value pairs in a HashMap

    • Try to get the corresponding value from the HashMap based on the full class name of the incoming interface class, and return the empty collection if none is found

  • Iterate through the list of all class names of the implementation class. For each implementation class, the corresponding constructor is invoked using reflection mechanism to instantiate an object, eventually generating a list of instantiated objects

  • Sort the list of instantiated objects

    • If an object implements the Ordered interface or has the @ordered annotation, get the order value for that object

    • If an object has the @priority annotation, get the Priority value for that object

    • Order each object in ascending order based on its order or priority value

  1. Line 284: capture and instantiate ApplicationContextInitializer related classes, after it is assigned to the instance attributes

  2. Line 285: Gets and instantiates the class associated with ApplicationListener, and then assigns it to the instance’s properties

  3. Line 286: Detects the properties of the main class object and assigns them to the instance

  • The detection methods are as follows:

    • Iterate through the current call stack

    • Find a stack element whose method name is equal to “main” and whose class is the class of the main class


To sum up:

When an application calls an entry class, SpringBoot creates an instance of SpringApplication and calls its run method.

When creating an instance, SpringBoot does some checking and instantiating:

  • Detection Application Type
  • Detect the main class
  • Instantiate Bootstraper related classes
  • Instantiation ApplicationContextInitializer related classes
  • Instantiate the class associated with ApplicationListener

Stay tuned for SpringApplication’s run method source code analysis in the next series of articles.