springboot版本控制器
SpringBoot應用的pom.xml中引入了一個父項目parent:spring-boot-starter-parent,spring-boot-starter-parent的父項目為spring-boot-dependencies。spring-boot-dependencies相當於SpringBoot的版本仲裁中心,其中有個properties標簽指定了一些依賴的版本:解決了一些版本沖突的問題,有了它我們在導入依賴時默認不需要寫版本號,但是沒有在此處聲明版本號的依賴依然需要寫明版本。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/>
</parent>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.1</version>
</parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.1</version>
<packaging>pom</packaging>
properties標簽:
<properties>
<activemq.version>5.16.3</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.92</appengine-sdk.version>
<artemis.version>2.19.0</artemis.version>
<aspectj.version>1.9.7</aspectj.version>
<assertj.version>3.21.0</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<awaitility.version>4.1.1</awaitility.version>
<build-helper-maven-plugin.version>3.2.0</build-helper-maven-plugin.version>
<byte-buddy.version>1.11.22</byte-buddy.version>
<caffeine.version>2.9.2</caffeine.version>
etc……
<properties>
版本仲裁:
1、引入依賴默認都可以不寫版本
2、引入非版本仲裁的jar,要寫版本號。
修改默認版本號:
查看spring-boot-dependencies里面規定當前依賴的版本用的 key。
1、引入依賴時直接寫上版本號
2、在當前項目里面重寫配置
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
這兩種方法其實都是利用maven提供的特性,就近優先原則,就是在當前項目中已經配置了某個依賴的版本號我就使用其版本號,如果當前項目中沒有配置其版本號,我就去其父項目中找其版本號。
版本依賴關系
ctrl + shift + alt + U
:以圖的方式顯示項目中依賴之間的關系。
springboot場景啟動器
spring-boot-starter場景啟動器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.6.1</version>
<scope>compile</scope>
</dependency>
springboot的各種各樣的 starters,有官方提供的,也有第三方開源出來。starter是springBoot的一個重要部分。通過starter,我們能夠快速的引入一個功能,而無需額外的配置。同時starter一般還會給我提供預留的自定配置選項,我們只需要在application.properties中設置相關參數,就可以實現配置的個性化。
springboot場景:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
<version>2.6.1</version>
</dependency>
自動配置
-
自動配好Tomcat
引入Tomcat依賴,配置Tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
-
自動配好SpringMVC
引入SpringMVC全套組件,自動配好SpringMVC常用組件(功能)
-
自動配好Web常見功能,如:字符編碼問題
-
SpringBoot幫我們配置好了所有web開發的常見場景
-
默認的包結構
主程序所在包及其下面的所有子包里面的組件都會被默認掃描進來,無需以前的包掃描配置想要改變掃描路徑,@SpringBootApplication(scanBasePackages="###.###")或者@ComponentScan 指定掃描路徑
@SpringBootApplication
等同於
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("包路徑")
-
各種配置擁有默認值
默認配置最終都是映射到某個類上,如:MultipartProperties
配置文件的值最終會綁定每個類上,這個類會在容器中創建對象
-
按需加載所有自動配置項
非常多的starter,引入了哪些場景這個場景的自動配置才會開啟,SpringBoot所有的自動配置功能都在 spring-boot-autoconfigure 包里面
springboot自動配置原理
@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
-
@SpringBootConfiguration:標記當前類為配置類
-
@EnableAutoConfiguration:開啟自動配置
-
@ComponentScan:掃描主類所在的同級包以及下級包里的Bean
關鍵是@EnableAutoConfiguration
@EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
/**
* Environment property that can be used to override when auto-configuration is
* enabled.
*/
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
@AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class) //給容器中導入一個組件
public @interface AutoConfigurationPackage {}
@AutoConfigurationPackage利用Registrar給容器中導入一系列組件
@Import(AutoConfigurationImportSelector.class)
@EnableAutoConfiguration其中最關鍵的要屬@Import(AutoConfigurationImportSelector.class),借助AutoConfigurationImportSelector,@EnableAutoConfiguration可以幫助SpringBoot應用將所有符合條件的@Configuration配置都加載到當前SpringBoot創建並使用IOC容器。
AutoConfigurationImportSelector中方法的作用:
1、利用getAutoConfigurationEntry(annotationMetadata);給容器中批量導入一些組件
2、調用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)獲取到所有需要導入到容器中的配置類
3、利用工廠加載 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的組件
4、從META-INF/spring.factories位置來加載一個文件。默認掃描我們當前系統里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
在AutoConfigurationImportSelector類中可以看到通過 SpringFactoriesLoader(Spring框架原有的一個工具類).loadFactoryNames()
把 spring-boot-autoconfigure.jar/META-INF/spring.factories中每一個xxxAutoConfiguration文件都加載到容器中,spring.factories文件里每一個xxxAutoConfiguration文件一般都會有下面的條件注解:
@ConditionalOnClass : classpath中存在該類時起效
@ConditionalOnMissingClass : classpath中不存在該類時起效
@ConditionalOnBean : DI容器中存在該類型Bean時起效
@ConditionalOnMissingBean : DI容器中不存在該類型Bean時起效
@ConditionalOnSingleCandidate : DI容器中該類型Bean只有一個或@Primary的只有一個時起效
@ConditionalOnExpression : SpEL表達式結果為true時
@ConditionalOnProperty : 參數設置或者值一致時起效
@ConditionalOnResource : 指定的文件存在時起效
@ConditionalOnJndi : 指定的JNDI存在時起效
@ConditionalOnJava : 指定的Java版本存在時起效
@ConditionalOnWebApplication : Web應用環境下起效
@ConditionalOnNotWebApplication : 非Web應用環境下起效
AutoConfigurationImportSelector中的方法getCandidateConfigurations,得到待配置的class的類名集合,這個集合就是所有需要進行自動配置的類,而是是否配置的關鍵在於META-INF/spring.factories文件中是否存在該配置信息。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
所有需要配置的類全路徑都在文件\spring-boot-autoconfigure\2.6.1\spring-boot-autoconfigure-2.6.1.jar!\META-INF\spring.factories中,每行一個配置,多個類名逗號分隔,而\表示忽略換行。(以下截取部分)
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
# 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,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
……
總結:
-
SpringBoot先加載所有的自動配置類 xxxxxAutoConfiguration
-
每個自動配置類按照條件進行生效,默認都會綁定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件進行了綁定
-
生效的配置類就會給容器中裝配很多組件
-
只要容器中有這些組件,相當於這些功能就有了
-
定制化配置
-
- 用戶直接自己@Bean替換底層的組件
- 用戶去看這個組件是獲取的配置文件什么值就去修改。