1. SpringApplication
We first create a basic SpringBoot project, then find the SpringApplication.run() method, and check the calls inside.
We will find that run() is called again at this time, click on the run() method,
which is a new SpringApplication, we new SpringApplication(SpringbootApplication.class).run(args);
replace it in the main() method, SpringApplication.run(SpringbootApplication.class, args);
and run, we can find that the fresh fruits of the two are the same.
We can see that the run method has a return value. The object type is ConfigurableApplicationContext. This class can set up our Banner. That is, we usually start the icon displayed and
enter new SpringApplication(SpringbootApplication.class).run(args);
the run() method. You can view
such a piece of code. Why do you want to circle start() and stop()? In fact, let's take a look at the class of stopWatch.
System.nanoTime() returns the most accurate current value of the available system timer, in nanoseconds. This is why we can see the start time in the console, so seeing start() and stop() means that the start is over. We will analyze this piece of code later.
Let's see new SpringApplication(SpringbootApplication.class).run(args);
this paragraph again , take a look at his execution method, click in, he will execute the this() method before executing the run method. Then we look at the this() method.
Let's start from here
this.webApplicationType = WebApplicationType.deduceFromClasspath();
Click the way into
which
private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";
private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";
private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
See if there is org.springframework.web.reactive.DispatcherHandler
the ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)
same thing afterwards . If all are true, use the responsive WEB to start,
if it does not exist , it will not "javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext"
be embedded in the web server.
Otherwise, embed the servlet server.
In fact, the data he returns are only enumerated and packaged
. We also explain the content of this picture.
NONE
: The application should not be run as a web application, nor should the embedded web server be started.
SERVLET
: The application should be run as a servlet-based web application and the embedded servlet web server should be started.
REACTIVE
: The application should run as a responsive web application, and the embedded responsive web server should be started.
This webApplicationType can also be set by ourselves, in yml, as follows:
-
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
By default, find all ApplicationContextInitializers configured by META-INF/spring.factories from the paths of these two jar packages; then save them
-
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
Find all ApplicationListeners configured in META-INF/spring.factories from the classpath. Generally, query the configuration in the picture above. Both of them will scan spring.factories in all jar packages -
this.mainApplicationClass = deduceMainApplicationClass();
Get the main class of the Main function
2.@EnableAutoConfiguration to
view the source code
Borrowing @Import to register AutoConfigurationImportSelector,
then let's look at AutoConfigurationImportSelector.java to
see this method
getAutoConfigurationEntry() and then see the getCandidateConfigurations() method, click in to see that the
getSpringFactoriesLoaderFactoryClass() method is called, and we see SpringFactoriesLoader. You should think of the spring.factories file quickly, and then scan the file in the jar package. We can take a look.
There are a
total of 100+ in it, and some of them will not be injected because they are not quoted.
In the previous article, we all know that the most important thing about SpringMVC is DispatcherServlet, and a search inside it really has something about him.
There is also a ServletWebServerFactoryAutoConfiguration, which is ServletFaactory. Let's take it out and see what he has done.
The circled location should be familiar. This is the Embedded that we manually start tomcat before, right? This is the last thing, let's first check this Bean==>tomcatServletWebServerFactoryCustomizer should also be in the above picture, let's see what its underlying layer is.
Should be familiar? We will often use server.xxx in yml
Okay, now let's check the ServletWebServerFactoryConfiguration.EmbeddedTomcat just mentioned, let
's click directly into it.
He used @Bean to register the tomcatServletWebServerFactory. Let’s take a look at the registered bean and find the getWebServer() method.
This should be familiar. Here we are similar to this operation when manually starting tomcat. Here is to start tomcat, we are creating a breakpoint in this part. (Subsequent use)
We will look back at the DispatcherServletAutoConfiguration bean. Click to enter
Here we can find DispatcherServletConfiguration, we can see that @Bean is used, and DispatcherServlet is directly registered.
We can make a breakpoint in this method at will. Now let’s think about whether DispatcherServlet is created first or tomcat is started first. Let’s Debug directly. We will find that Tomcat will be started first and then DispatcherServlet will be created.