?歡迎光臨小站:致橡樹
Spring Boot Starter 的核心設計理念是 約定優于配置,其核心實現基于 自動配置(Auto-Configuration) 和 條件化注冊(Conditional Registration)。以下是其生效原理:
約定大于配置
通過預定義合理的默認行為和規范,減少開發者需要手動配置的步驟。比較顯著的變化就是減少XML配置。還有一些實際體現如下所示:
-
項目結構約定
-
默認目錄結構:如
src/main/java
存放代碼,src/main/resources
存放配置文件。 -
配置文件命名:
application.properties
或application.yml
自動被加載,無需顯式指定路徑。
-
-
自動配置(Auto-Configuration)
-
條件化 Bean 注冊:根據類路徑依賴(如存在
DataSource
類)自動配置數據庫連接池。 -
默認參數值:如嵌入式 Tomcat 默認端口為
8080
,無需手動指定。
-
-
Starter 依賴
-
依賴聚合:引入
spring-boot-starter-web
即自動包含 Web 開發所需的所有依賴(如 Tomcat、Jackson、Spring MVC)。 -
開箱即用:無需手動管理版本兼容性。
-
-
RESTful 路由映射
-
注解驅動:通過
@GetMapping("/path")
即可定義接口,無需在 XML 中配置路由規則。
-
自動配置機制
觸發階段:@EnableAutoConfiguration
-
應用啟動時,
@SpringBootApplication
組合了@EnableAutoConfiguration
,觸發自動配置流程。 -
AutoConfigurationImportSelector
被調用,負責加載所有候選的自動配置類。
public String[] selectImports(AnnotationMetadata metadata) {// 1. 加載所有候選自動配置類List<String> configurations = getCandidateConfigurations();// 2. 去重、過濾、排序configurations = removeDuplicates(configurations);configurations = filter(configurations, autoConfigurationMetadata);return configurations.toArray(new String[0]);
}
加載與篩選:spring.factories
-
加載所有候選配置類
從所有META-INF/spring.factories
文件中讀取EnableAutoConfiguration
對應的配置類。在 Spring Boot 3.x 中,自動配置類的加載方式從 spring.factories 過渡到 AutoConfiguration.imports,并引入了 ImportCandidates 類來處理這一變化。 -
去重與過濾
移除重復的配置類,并通過條件注解(如@ConditionalOnClass
,@ConditionalOnMissingBean
) 有選擇的保留當前環境的配置類。-
@ConditionalOnClass:類路徑存在指定類時生效
-
@ConditionalOnMissingBean:容器中不存在指定 Bean 時生效
-
@ConditionalOnProperty:配置屬性匹配時生效
-
-
排序
根據@AutoConfigureOrder
或@AutoConfigureAfter
調整配置類的加載順序。
Bean 注冊
-
篩選后的自動配置類被解析為標準的
@Configuration
類。 -
每個配置類中的
@Bean
方法根據條件注解動態注冊 Bean 到 Spring 容器。
編寫自定義Spring Boot Starter
項目結構規劃
建議分為兩個模塊:
-
自動配置模塊:包含核心邏輯和自動配置類(如
hello-spring-boot-autoconfigure
)。 -
Starter模塊:空項目,僅作為依賴聚合(如
hello-spring-boot-starter
)。
hello-spring-boot-starter-parent(父POM)
├── hello-spring-boot-autoconfigure(自動配置模塊)
└── hello-spring-boot-starter(Starter模塊)
hello-spring-boot-starter/
├── hello-spring-boot-autoconfigure/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/com/example/autoconfigure/
│ │ │ │ ├── HelloAutoConfiguration.java
│ │ │ │ ├── HelloProperties.java
│ │ │ │ └── HelloService.java
│ │ │ └── resources/
│ │ │ └── META-INF/
│ │ │ └── spring.factories
│ │ └── test/
│ └── pom.xml
├── hello-spring-boot-starter/
│ └── pom.xml
└── pom.xml
創建自動配置模塊(hello-spring-boot-autoconfigure)
添加Maven依賴
<!-- pom.xml -->
<dependencies><!-- Spring Boot 自動配置基礎依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId><version>3.1.5</version></dependency><!-- 可選:配置屬性處理 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><version>3.1.5</version><optional>true</optional></dependency>
</dependencies>
定義核心服務類
public class HelloService {private String message = "Hello, World!"; // 默認消息public String sayHello() {return message;}// Getter和Setter用于通過配置修改messagepublic String getMessage() { return message; }public void setMessage(String message) { this.message = message; }
}
定義配置屬性類(可選)
@ConfigurationProperties(prefix = "hello")
public class HelloProperties {private String message = "Hello, World!";// Getter和Setterpublic String getMessage() { return message; }public void setMessage(String message) { this.message = message; }
}
編寫自動配置類
@Configuration
@EnableConfigurationProperties(HelloProperties.class) // 啟用配置屬性
@ConditionalOnClass(HelloService.class) // 當HelloService在類路徑時生效
public class HelloAutoConfiguration {@Bean@ConditionalOnMissingBean // 當用戶未自定義HelloService時生效public HelloService helloService(HelloProperties properties) {HelloService service = new HelloService();service.setMessage(properties.getMessage());return service;}
}
注冊自動配置
在 resources/META-INF/
下創建 spring.factories
文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfigure.HelloAutoConfiguration
創建Starter模塊(hello-spring-boot-starter)
添加Maven依賴
<!-- pom.xml -->
<dependencies><!-- 引入自動配置模塊 --><dependency><groupId>com.example</groupId><artifactId>hello-spring-boot-autoconfigure</artifactId><version>1.0.0</version></dependency>
</dependencies>
使用自定義Starter
在應用中引入Starter依賴
<!-- 用戶項目的pom.xml -->
<dependency><groupId>com.example</groupId><artifactId>hello-spring-boot-starter</artifactId><version>1.0.0</version>
</dependency>
在代碼中注入Bean
@RestController
public class HelloController {@Autowiredprivate HelloService helloService;@GetMapping("/hello")public String hello() {return helloService.sayHello();}
}
自定義配置(可選)
在 application.properties
中修改消息:
hello.message=你好, Spring Boot!