SpringBoot enters tomcat startup process and principle

For a Spring Boot Web project, a major dependency sign is the spring-boot-starter-web starter. The spring-boot-starter-web module does not actually have code in Spring Boot, but is only in pom.xml. It carries some dependencies, including web, webmvc and tomcat, etc.

for example:Create a new SpringBoot-Web project.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Click pom.xml and find there have dependencies of tomcat

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>3.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>

Exploring step by step from the Spring Boot startup entry point

run method

public static ConfigurableApplicationContext run(Class primarySource,
String… args) {
return run(new Class[] { primarySource }, args);
}
// Continue clicking into the run method
public static ConfigurableApplicationContext run(Class<?>[] primarySources,
String[] args) {
return new SpringApplication(primarySources).run(args);
}

After entering this run method, we can see some familiar initialization events. The main process is also completed here.

The code flow is roughly as follows:

/**
* Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
/**1、Configure system properties*/
configureHeadlessProperty();
/**2.Get listeners*/
SpringApplicationRunListeners listeners = getRunListeners(args);
/**Publish application starting event */
listeners.starting();
try {
/** 3.Initialize parameters */
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
/** 4.Configure environment*/
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);

configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
/**5.Create application context*/
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
/**6.Preprocess the context*/
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);

refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
/** 7.Publish application started event */
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}

try {
/** 8.Publish application running event */
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}

SpringBoot is started mainly by instantiating SpringApplication.

This process is actually not complicated. It is to start the Tomcat container during the process of refreshing the Spring context, bind the current application to a Context, and then add the Host.

In the spring-boot-autoconfigure module, there is a auto-configuration class called ServletWebServerFactoryAutoConfiguration that handles the configuration related to the WebServer.

The code snippet is as this:

@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration

These two conditions indicate that the current runtime environment is based on the Servlet standard specification for web services:

ConditionalOnClass(ServletRequest.class): Indicates that the servlet-api dependency must be present.
ConditionalOnWebApplication(type = Type.SERVLET): Indicates that it is only applicable to Servlet-based web applications.

The usage of @EnableConfigurationProperties(ServerProperties.class) is to load the ServerProperties configuration, which includes common configuration properties like server.port.

By using @Import, it imports the relevant auto-configuration classes related to the embedded container, such as EmbeddedTomcat, EmbeddedJetty, and EmbeddedUndertow.

In summary, the ServletWebServerFactoryAutoConfiguration auto-configuration class performs the following tasks:

  • Imports the inner class BeanPostProcessorsRegistrar, which implements ImportBeanDefinitionRegistrar to register additional BeanDefinition.
  • Imports the configurations related to embedded containers, such as ServletWebServerFactoryConfiguration.EmbeddedTomcat (we primarily focus on Tomcat-related configurations).
  • Registers two beans of type WebServerFactoryCustomizer: ServletWebServerFactoryCustomizer and TomcatServletWebServerFactoryCustomizer.

The principle of embedded web servers is just a few points like this, it’s not very difficult.

No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
:D
Emoji
picure
black!
Previous
Next