SpringBoot source code analysis ------ creation of mvc container and start of tomcat

1. SpringApplication
We first create a basic SpringBoot project, then find the SpringApplication.run() method, and check the calls inside.
Insert picture description here
We will find that run() is called again at this time, click on the run() method,
Insert picture description here
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
Insert picture description here
enter new SpringApplication(SpringbootApplication.class).run(args);the run() method. You can view
Insert picture description heresuch 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.
Insert picture description hereSystem.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.
Insert picture description hereLet's start from here

  1. this.webApplicationType = WebApplicationType.deduceFromClasspath();
    Click the way into
    Insert picture description here
    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
Insert picture description here
. 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:
Insert picture description here

  1. 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
    Insert picture description here

  2. 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

  3. this.mainApplicationClass = deduceMainApplicationClass();
    Get the main class of the Main function

2.@EnableAutoConfiguration to
view the source code
Insert picture description here
Borrowing @Import to register AutoConfigurationImportSelector,
then let's look at AutoConfigurationImportSelector.java to
Insert picture description here
see this method
Insert picture description heregetAutoConfigurationEntry() and then see the getCandidateConfigurations() method, click in to see that the
Insert picture description hereInsert picture description here
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
Insert picture description here
Insert picture description here
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.
Insert picture description here
There is also a ServletWebServerFactoryAutoConfiguration, which is ServletFaactory. Let's take it out and see what he has done.
Insert picture description here
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.
Insert picture description here
Insert picture description here
Should be familiar? We will often use server.xxx in yml
Insert picture description here

Okay, now let's check the ServletWebServerFactoryConfiguration.EmbeddedTomcat just mentioned, let
's click directly into it.
Insert picture description here
He used @Bean to register the tomcatServletWebServerFactory. Let’s take a look at the registered bean and find the getWebServer() method.
Insert picture description here
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
Insert picture description here
Here we can find DispatcherServletConfiguration, we can see that @Bean is used, and DispatcherServlet is directly registered.
Insert picture description here
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.

Guess you like

Origin blog.csdn.net/weixin_43911969/article/details/115058311