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.