Spring Boot 是一個用于簡化 Spring 應用程序開發的框架。它通過提供默認配置和自動配置的方式,使得開發者能夠快速搭建和運行 Spring 應用程序。Spring Boot 的底層原理涉及到多個方面,包括自動配置、依賴管理、嵌入式服務器、啟動流程等。本文將深入探討 Spring Boot 的底層原理,幫助讀者更好地理解和使用 Spring Boot。
自動配置是 Spring Boot 的核心特性之一。它通過分析項目的依賴關系和配置文件,自動配置 Spring 應用程序的各個組件。自動配置的實現主要依賴于 @EnableAutoConfiguration
注解和 spring.factories
文件。
@EnableAutoConfiguration
注解是 Spring Boot 自動配置的入口。它通過 @Import
注解引入了 AutoConfigurationImportSelector
類,該類負責加載自動配置類。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
spring.factories
文件是 Spring Boot 自動配置的關鍵文件之一。它位于 META-INF
目錄下,用于定義自動配置類。Spring Boot 在啟動時會掃描所有 spring.factories
文件,并加載其中定義的自動配置類。
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
...
Spring Boot 通過 spring-boot-starter
依賴管理機制,簡化了項目的依賴配置。每個 spring-boot-starter
都包含了一組相關的依賴,開發者只需引入相應的 starter
,即可自動引入所需的依賴。
spring-boot-starter-parent
是 Spring Boot 項目的父 POM,它定義了一系列默認的依賴管理和插件配置。通過繼承 spring-boot-starter-parent
,開發者可以簡化項目的配置。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
spring-boot-starter-web
是 Spring Boot 提供的用于開發 Web 應用的 starter
。它包含了 Spring MVC、Tomcat 等依賴,開發者只需引入該 starter
,即可快速搭建一個 Web 應用。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot 支持嵌入式服務器,開發者無需將應用部署到外部服務器中,即可直接運行應用。Spring Boot 默認使用 Tomcat 作為嵌入式服務器,但也支持 Jetty、Undertow 等其他服務器。
Tomcat 是 Spring Boot 默認的嵌入式服務器。Spring Boot 通過 spring-boot-starter-web
引入了 Tomcat 依賴,并在應用啟動時自動配置和啟動 Tomcat。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
Jetty 是另一個常用的嵌入式服務器。開發者可以通過排除 spring-boot-starter-tomcat
并引入 spring-boot-starter-jetty
,來使用 Jetty 作為嵌入式服務器。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Spring Boot 的啟動流程主要包括以下幾個步驟:
application.properties
或 application.yml
配置文件,并根據配置內容進行相應的配置。AnnotationConfigApplicationContext
或 AnnotationConfigServletWebServerApplicationContext
,用于管理 Spring Bean。spring.factories
文件中的配置,加載并執行自動配置類。SpringApplication.run()
方法,啟動應用并進入運行狀態。Spring Boot 的自動配置是通過 @Conditional
注解和 Condition
接口實現的。@Conditional
注解用于根據條件決定是否加載某個配置類或 Bean,而 Condition
接口則用于定義具體的條件邏輯。
@Conditional
注解是 Spring 框架提供的注解,用于根據條件決定是否加載某個配置類或 Bean。Spring Boot 在此基礎上擴展了一系列條件注解,如 @ConditionalOnClass
、@ConditionalOnMissingBean
等。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {
Class<?>[] value() default {};
String[] name() default {};
}
Condition
接口是 Spring 框架提供的接口,用于定義條件邏輯。開發者可以通過實現 Condition
接口,自定義條件判斷邏輯。
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
Spring Boot 的自動配置加載過程主要包括以下幾個步驟:
spring.factories
文件:Spring Boot 會掃描所有 META-INF/spring.factories
文件,并加載其中定義的自動配置類。@Conditional
注解的條件,過濾掉不符合條件的自動配置類。Spring Boot 的自動配置機制是可擴展的,開發者可以通過自定義自動配置類,擴展 Spring Boot 的自動配置功能。
開發者可以通過定義自動配置類,并添加 @Configuration
和 @Conditional
注解,來實現自定義的自動配置。
@Configuration
@ConditionalOnClass(MyService.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new MyService();
}
}
開發者可以通過在 META-INF/spring.factories
文件中注冊自動配置類,使其在應用啟動時被加載。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration
Spring Boot 的依賴管理是通過 Maven 或 Gradle 的依賴管理機制實現的。Spring Boot 提供了一系列 spring-boot-starter
依賴,每個 starter
都包含了一組相關的依賴,開發者只需引入相應的 starter
,即可自動引入所需的依賴。
spring-boot-starter-parent
是 Spring Boot 項目的父 POM,它定義了一系列默認的依賴管理和插件配置。通過繼承 spring-boot-starter-parent
,開發者可以簡化項目的配置。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
spring-boot-dependencies
是 Spring Boot 提供的依賴管理 POM,它定義了一系列常用的依賴版本。通過引入 spring-boot-dependencies
,開發者可以統一管理項目的依賴版本。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Spring Boot 的依賴管理機制是可擴展的,開發者可以通過自定義 starter
,擴展 Spring Boot 的依賴管理功能。
開發者可以通過定義 starter
,并添加 spring.factories
文件,來實現自定義的依賴管理。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-library</artifactId>
</dependency>
</dependencies>
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration
開發者可以通過在 META-INF/spring.factories
文件中注冊 starter
,使其在應用啟動時被加載。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration
Spring Boot 的嵌入式服務器是通過 spring-boot-starter-web
依賴實現的。Spring Boot 默認使用 Tomcat 作為嵌入式服務器,但也支持 Jetty、Undertow 等其他服務器。
Tomcat 是 Spring Boot 默認的嵌入式服務器。Spring Boot 通過 spring-boot-starter-web
引入了 Tomcat 依賴,并在應用啟動時自動配置和啟動 Tomcat。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
Jetty 是另一個常用的嵌入式服務器。開發者可以通過排除 spring-boot-starter-tomcat
并引入 spring-boot-starter-jetty
,來使用 Jetty 作為嵌入式服務器。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Spring Boot 提供了豐富的配置選項,開發者可以通過 application.properties
或 application.yml
文件,配置嵌入式服務器的各項參數。
開發者可以通過 server.port
屬性,配置嵌入式服務器的端口。
server.port=8081
開發者可以通過 server.servlet.context-path
屬性,配置嵌入式服務器的上下文路徑。
server.servlet.context-path=/myapp
開發者可以通過 server.ssl
屬性,配置嵌入式服務器的 SSL 證書。
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=secret
Spring Boot 的嵌入式服務器機制是可擴展的,開發者可以通過自定義配置類,擴展 Spring Boot 的嵌入式服務器功能。
開發者可以通過定義配置類,并添加 @Configuration
和 @Conditional
注解,來實現自定義的嵌入式服務器配置。
@Configuration
@ConditionalOnClass(Tomcat.class)
public class MyTomcatConfiguration {
@Bean
public TomcatServletWebServerFactory tomcatFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.setPort(8081);
return factory;
}
}
開發者可以通過在 META-INF/spring.factories
文件中注冊配置類,使其在應用啟動時被加載。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyTomcatConfiguration
Spring Boot 的啟動流程是通過 SpringApplication
類實現的。SpringApplication
類負責加載配置文件、創建應用上下文、執行自動配置、啟動嵌入式服務器等操作。
SpringApplication
類是 Spring Boot 啟動流程的核心類。它提供了 run()
方法,用于啟動 Spring Boot 應用。
public class SpringApplication {
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
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) {
this.resourceLoader = resourceLoader;
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
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;
}
}
Spring Boot 的啟動流程主要包括以下幾個步驟:
application.properties
或 application.yml
配置文件,并根據配置內容進行相應的配置。AnnotationConfigApplicationContext
或 AnnotationConfigServletWebServerApplicationContext
,用于管理 Spring Bean。spring.factories
文件中的配置,加載并執行自動配置類。SpringApplication.run()
方法,啟動應用并進入運行狀態。Spring Boot 的啟動流程是可擴展的,開發者可以通過自定義 ApplicationRunner
或 CommandLineRunner
,擴展 Spring Boot 的啟動流程。
ApplicationRunner
是 Spring Boot 提供的接口,用于在應用啟動后執行一些操作。開發者可以通過實現 ApplicationRunner
接口,自定義啟動后的操作。
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("Application started with arguments: " + Arrays.toString(args.getSourceArgs()));
}
}
CommandLineRunner
是 Spring Boot 提供的另一個接口,用于在應用啟動后執行一些操作。開發者可以通過實現 CommandLineRunner
接口,自定義啟動后的操作
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。