SpringBoot自動裝配
- 前言
- @SpringBootConfiguration
- @EnableAutoConfiguration(重要)
-
- AutoConfigurationImportSelector.class
-
- getAutoConfigurationEntry()
-
- getCandidateConfigurations()
- META-INF/spring.factories
-
- EmbeddedWebServerFactoryCustomizerAutoConfiguration
- WebMvcAutoConfiguration
- ServletWebServerFactoryAutoConfiguration
- ThymeleafAutoConfiguration
- TransactionAutoConfiguration
前言
本文基于SpringBoot2.1.xx版本
提示:以下是本篇文章正文内容,可供參考
@SpringBootConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Target(ElementType.TYPE): 這是一個接口或者是類或者是枚舉
@Retention(RetentionPolicy.RUNTIME) : 會在class位元組碼檔案中存在,在運作時可以通過反射擷取到
@Document:該注解将被包含在javadoc中
@Configuration:表示加載IOC容器 使這個類成為了一個IOC容器配置類
可以再點進去看一下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Component:納入Spring容器中
@EnableAutoConfiguration(重要)
這個注解的意思就是開啟自動配置的功能。我們點進來看
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
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 {};
}
@Inherited:子類可以繼承父類中的該注解
@AutoConfigurationPackage:将主配置類所在的包作為自動配置包進行管理
@Import:自動裝配導入的選擇器
AutoConfigurationImportSelector.class
這裡點開AutoConfigurationImportSelector:
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
我們主要關注selectImports()這個方法,這個方法就是我們選擇導入的類。
//擷取自動裝配的類
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);
getAutoConfigurationEntry()
點開getAutoConfigurationEntry():
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
我們主要就是關注這行代碼,這行代碼就是擷取到我們的需要自動裝配的類然後以List< String >的形式進行一個存儲
getCandidateConfigurations()
點開getCandidateConfigurations():
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;
}
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.");
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.");
這個斷言的意思是如果發生了某些錯誤比如為空的話,就會輸出這個異常資訊,意思就是在META-INF/spring.factories下找不到這些自動裝配的類(factories也就是工廠)。spring.factories裡面都是一些自動裝配的類,然後這些類都是一個以String形式存儲的。
META-INF/spring.factories
org.springframework.boot:spring-boot-test-autoconfigure:2.x.xx.RELEASE
如果實在不好找的話也可以選中spring.factories 然後點選
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSPj1mYoR2MiRnRHplb1cVY3ZkMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4EDN0QTO1ITM3EDNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
我們找到jar中找到這個autoconfigure.jar之後然後打開META-INF/spring.factories就能看到這些自動裝配的類了。
EmbeddedWebServerFactoryCustomizerAutoConfiguration
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
自動裝配Servlet
@ConditionalOnClass:在滿足條件的時候就會加載Tomcat。這個也就是我們常說的SpringBoot中的内置Tomcat了。
點選進來看看就能夠看到Tomcal的一些配置資訊了,比如端口這些的
WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
自動裝配SpringMVC
ServletWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
自動裝配并啟動Tomcat伺服器
ThymeleafAutoConfiguration
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
自動裝配SpringBoot預設模闆引擎Thymeleaf
TransactionAutoConfiguration
自動裝配事務
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
這裡面還有很多的自動裝配類,如果感興趣的話可以自行看看。今天的分享就到此為止啦,謝謝查閱。如果有什麼不對的地方歡迎指點!