We have already understood the SpringBoot source code analysis before --- the creation of the mvc container and the startup of tomcat. The startup of SpringBoot is through the internal new object, and the run() method is performed.
Now let's take a look at each step in the run() method.
SpringApplication.run()
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] {
ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
-
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
Declare the IOC container -
SpringApplicationRunListeners listeners = getRunListeners(args);
Get SpringApplicationRunListeners, there is only one EventPublishingRunListener inside, we can see what this method is executed, we
must be familiar with this getSpringFactoriesInstances() method, he is to read a certain class in the META-INF/factories file, we can hold it SpringApplicationRunListener go to the springboot package to search, you can find that there is only one
-
listeners.starting();
Callback all the methods to get SpringApplicationRunListener.starting()
At present, we don't have a custom SpringApplicationRunListener subclass method, so only one EventPublishingRunListener.starting() is called back. We can also look at the internal code, that is, a for loop is called back
-
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
Wrap args -
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
Key points
Enter the code.
Here you can see that only some data has been initialized. Go back to the front and look at the load() method.
It’s not that I said,
thereis really a lot of packaging.There is another name here. Let’s check the getSearchNames() method.
And look at this constant.
Here is a foreach, we can see what this Lambda expression specifically means. Go in and take a look at the getSearchLocations() method.
You can view the constant data of DEFAULT_SEARCH_LOCATIONS.
However, this data is the following parameter location.
In this method, you can first look at the three variables of loader, location, and name.
1. Loader
contains xml, yaml, yml, properties. We should be familiar with these variables. These are the suffixes of configuration files.
2.location
has been mentioned above
3.name
has been mentioned above
From these three points, we can know that the configuration file name read by defaultapplication
, the configuration file can exist in theclasspath:/,classpath:/config/,file:./,file:./config/*/,file:./config/
directory, and the type of configuration file can bexml、yaml、yml、properties
.
Going back to the front, continue to look at this heavy packaging,
you can put it forward first, in this method, you start to get the information in the configuration file, and it will be written into springboot soon.
In theList<Document> documents = loadDocuments(loader, name, resource);
access to information in the configuration file here. Currently there is only one data in my configuration file
We can debug to this position. You can see after this line of code runs.
You have already got the data.
After
getting the data here, you will return to the addLoadedPropertySources() method to take a look at this method.
If you have used the Properties file to read friends, you should be familiar with it. This is to
run toaddLoadedPropertySource(destination, lastAdded, source);
this code after adding resources to the project .
Add the data to the SpringBoot project. So far.ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
It's over. -
Banner printedBanner = printBanner(environment);
Output SpringBoot logo icon -
context = createApplicationContext();
Create SpringBoot context -
refreshContext(context);
Refresh the context. What is going on here is the startup of tomcat, and
we mentioned these two methods in the previous article to load springmvc . You can put a breakpoint in it and check its call chain.
-
afterRefresh(context, applicationArguments);
Define an empty template method for other subclasses to implement -
listeners.started(context);
Use broadcast and callback mechanisms to notify the listener that the SpringBoot container has started successfully -
listerens.running(context)
Use broadcast and callback mechanisms to notify the listener that the SpringBoot container has started successfully and can execute other requests -
Return the current context.
Even if it's over here, is it awkward to read the configuration file? It's right to be stunned, we will come to a simple version ( SpringBoot source code analysis-easy configuration file reading ), and then look back and you can understand.
Before that, ask a question.
What is the difference between classpath reading configuration file and file reading configuration file?
classpath读取的配置文件是编译后的文件,而file的配置文件是没有经过编译的文件。