SpringBoot 核心理論
1.SpringBoot
1.1 概念
SpringBoot是由Pivotal團隊在2013年開始研發、2014年4月釋出第一個版本的全新開源的輕量級框架。它基於Spring4.0設計,不僅繼承了Spring框架原有的優秀特性,而且還通過簡化配置來進一步簡化了Spring應用的整個搭建和開發過程。另外SpringBoot通過整合大量的框架使得依賴包的版本衝突,以及引用的不穩定性等問題得到了很好的解決。
- 設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。
- 核心:自動配置、基於 約定大於配置 原則。
- 父依賴維護 SpringBoot 版本號即可
- 核心註解:@EnableAutoConfiguration
1.2 核心依賴
SpringBoot 父依賴為核心依賴,其中預設管理了很多 jar 包的版本,所以我們再根 pom.xml 中如果不需要指定特殊的版本,可不指定 jar 包版本。
檢視核心依賴
- 進入 spring-boot-starter-parent
<parent> <groupId>org.springframework.boot</groupId> <!-- 跟進 以下目錄,檢視父依賴的 --> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
- 進入spring-boot-dependencies
<!-- 再進入 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
</parent>
進入 spring-boot-dependencies-2.3.1.RELEASE.pom 檔案後,可發現在 properties
dependencyManagement
中有很多依賴已經配置並指定版本號好。
1.3 自動裝配(核心)
SpringBoot 的核心就在於 自動裝配。
SpringBoot 自動裝配的過程:
SpringBoot 通過 @EnableAutoConfiguration 註解開啟自動裝配;載入 spring.factories 中註冊的各類 AutoConfiguration;當 AutoConfiguration 類滿足 @Conditional 註解中的條件時,則例項化該 AutoConfiguration 類中定義的 Bean,並注入 Spring 容器中。
@EnableAutoConfiguration
該註解由 @SpringBootApplication 引入,完成開啟自動裝配;掃描 autoconfigure jar 包 META-INF 下的 spring.factories 檔案,並載入其中註冊的 AutoConfigure 類等。
spring.factories
配置檔案,位於 autoconfigure jar 包 META-INF 目錄下;
AutoConfiguration
SpringBoot 中的自動配置類,例如 RedisAutoConfiguration 等;其中定義了三方元件整合 Spring 所需的初始化 Bean 和條件
@Conditional
SpringBoot 中以 @Conditional 開頭的條件註解;AutoConfiguration 需滿足其中的條件才可例項化
1.3 啟動器
各類三方元件starter
<!-- Spring web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot Mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- SpringBoot JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 阿里資料庫連線池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- SpringBoot Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1.4 註解
SpringBoot 專案建立完會生成 ***Application 啟動類;
package pers.vincent.matrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MatrixApplication {
public static void main(String[] args) {
SpringApplication.run(MatrixApplication.class, args);
}
}
核心註解:@SpringBootApplication
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.repository.Repository;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
// 排除指定自動配置類
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
// 排除指定自動配置名
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
// 指定掃描的基礎包,啟用註解元件的初始化
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
// 指定掃描的類,初始化
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
// Bean名稱生成器
@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
// 指定是否代理 @Bean 方法
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
結構:
@SpringBootApplication
- @SpringBootConfiguration
- @Configuration
- @Component
- @Configuration
- @EnableAutoConfiguration
- @AutoConfigurationPackage
- @Import(AutoConfigurationImportSelector.class)
- @ComponentScan
- @Repeatable(ComponentScans.class)
@SpringBootConfiguration: SpringBoot 配置
@Configuration:Spring 配置類
@Component:元件
@EnableAutoConfiguration:自動配置 (核心註解)
@AutoConfigurationPackage:自動配置包
@Import(AutoConfigurationPackages.Registrar.class):自動配置`包註冊`
@Import(AutoConfigurationImportSelector.class): 自動配置匯入選擇
@ConditionOnxxxx:如果條件都滿足,才能生效
@ComponentScan:掃描
其餘註解:
- @AliasFor:用於橋接到其他註解,其中的屬性指定所橋接的註解類
@EnableAutoConfiguration :
@Import(AutoConfigurationImportSelector.class)
AutoConfigurationImportSelector 核心功能解析:
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 載入 spring.factories 中的 EnableAutoConfiguration 的配置類
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 配置類去重
configurations = removeDuplicates(configurations);
/// 獲得被排除的類集合
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
// 檢查排除的類是否合法
checkExcludedClasses(configurations, exclusions);
// 配置類集合中取出被排查的類
configurations.removeAll(exclusions);
// 過濾自動載入元件
configurations = getConfigurationClassFilter().filter(configurations);
// 將配置類和排除類 通過事件傳入監聽器中
fireAutoConfigurationImportEvents(configurations, exclusions);
// 返回自動配置類全限定名陣列
return new AutoConfigurationEntry(configurations, exclusions);
}