Shallow analysis of SpringBoot boot flow

A. Startup class

1. @ SpringBootApplication annotation

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
Copy the code

Check out this blog post on the automatic configuration process

【Spring Boot】Spring Boot automatic configuration principle illustrated _ autumn sunset blog -CSDN blog

2. The main method

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

To go in

The static method first see method statement Returns a ConfigurableApplicationContext interface implementation class object

You can see there are a lot of implementation classes and subinterfaces so how do you choose an implementation class object? Continue with the source code with this question

PrimarySources // The class object of the main start class args // the start parameter of the main methodCopy the code

There’s a new instance of SpringApplication, calling the run method

new SpringApplication()

Follow up the new SpringApplication(primary resources) method

public SpringApplication(Class<? >... primarySources) { this(null, primarySources); }Copy the code

Create a new SpringApplication instance. The application context loads the bean from the specified primary source

Follow up on the construction method

ResourceLoader // the resourceLoader is null this. ResourceLoader = resourceLoader;Copy the code
PrimarySources // The source of the bean in the container is the bytecode object of the primary boot class at this timeCopy the code

It is asserted that primarySources cannot be null or an exception will be thrown

Assert.notNull(primarySources, "PrimarySources must not be null");
Copy the code

On the method parameter primarySources is a variable parameter and then primarySources becomes a LinkedHashSet

this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
Copy the code

The underlying LinkedHashSet is a list that keeps the storage in order

It then executes this line of code

this.webApplicationType = WebApplicationType.deduceFromClasspath();
Copy the code

So what is this webApplicationType and if you click on it you can see it’s an enumeration with three enumerations, right

/** * The application should not run as a web application and should not start an * embedded web server. This application should not run as a Web application, nor should it start an embedded Web server. */ NONE, /** * The application should run as a servlet-based web application and should start an * embedded servlet web server. The application should run as a Servlet-based Web application, And should start the embedded Servlet Web server */ servlet, /** * The application should run as a reactive web application and should start an * embedded reactive web server. The application should run as a REACTIVE Web application and should start an embedded REACTIVE Web server */ REACTIVE;Copy the code

Determine the current project type Here return WebApplicationType. SERVLET is the type of the current SpringApplication for Web applications, built-in SERVLET Web server

Next, the listener is set up

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
Copy the code

Then set the program entry

this.mainApplicationClass = deduceMainApplicationClass()
Copy the code

SpringApplication.run()

Now what does the run method do

StopWatch stopWatch = new StopWatch(); // stopwatch.start (); // Start the timerCopy the code

A system property called java.awt.headless is set

configureHeadlessProperty()
Copy the code

Gets a listener for the Spring application context bootstrap class,

SpringApplicationRunListeners listeners = getRunListeners(args)
Copy the code

The ApplicationStartingEvent event is published

listeners.starting();
Copy the code

Encapsulating parameters Parameters required by the SpringApplication bootstrap class

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args)
Copy the code

Prepare the environment

ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
Copy the code

Ignore unneeded beans based on the current environment

configureIgnoreBeanInfo(environment);
Copy the code

Print the Banner

Banner printedBanner = printBanner(environment)
Copy the code

See that webApplicationType is of type SERVLET before creating the ApplicationContext context

context = createApplicationContext()
Copy the code

Return AnnotationConfigServletWebServerApplicationContext bytecode object It then calls the BeanUtils instantiateClass instantiation

class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
		implements AnnotationConfigRegistry 
Copy the code

Inherited from ServletWebServerApplicationContext

The refresh context eventually reuses Spring’s refresh container approach

refreshContext(context);
Copy the code

Call ConfigurableApplicationContext. Refresh () method

Call again org. Springframework. Boot. Web. Servlet. Context. ServletWebServerApplicationContext# refresh

Last call org. Springframework. Context. Support. AbstractApplicationContext# refresh

Check out this blog post for 12 ways to refresh containers

【Spring】SpringIOC container startup process source code analysis and cycle dependency issues _ autumn sunset -CSDN blog

The last step is to stop the timer and print the log

        stopWatch.stop();

        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }


Copy the code