SpringBoot的自動配置原理

一、SpringBoot的自動配置原理

SpringBoot 的自動化配置讓我們的開發徹底遠離了 Spring 繁瑣的各種配置,讓我們專注於開發,但是SpringBoot 的自動化配置是怎麼實現的呢?下面爲你揭開 SpringBoot 自動化配置的神祕面紗。

所以今天來講講SpringBoot是如何實現自動配置的~

1.1三個重要的註解

我們可以發現,在使用main()啓動SpringBoot的時候,必不可少的註解@SpringBootApplication
在這裏插入圖片描述

我們可以點擊進去@SpringBootApplication註解中看看,它其實是由三個註解組成的組合註解:

在這裏插入圖片描述

  • @SpringBootConfiguration :底層是Configuration註解,說白了就是支持JavaConfig的方式來進行配置(使用Configuration配置類等同於XML文件)。
  • @EnableAutoConfiguration:開啓自動配置功能
  • @ComponentScan掃描註解,默認是掃描當前類下的package。將@Controller/@Service/@Component/@Repository等註解加載到IOC容器中。

1.2重點@EnableAutoConfiguration

我們知道SpringBoot可以幫我們減少很多的配置,也肯定聽過“約定大於配置”這麼一句話,那SpringBoot是怎麼做的呢?其實靠的就是**@EnableAutoConfiguration**註解。

簡單來說,這個註解可以幫助我們自動載入應用程序所需要的所有默認配置

如果你的類路徑下有tomcat-embedded.jar包,那麼你很可能就需要TomcatServletWebServerFactory

我們點進去看一下,發現有兩個比較重要的註解:

在這裏插入圖片描述

  • @AutoConfigurationPackage:自動配置包
  • @Import:給IOC容器導入組件

1.2.1 @AutoConfigurationPackage

網上將這個**@AutoConfigurationPackage註解解釋成自動配置包**,我們也看看@AutoConfigurationPackage裏邊有什麼:
在這裏插入圖片描述

我們可以發現,依靠的還是@Import註解,再點進去查看,我們發現重要的就是以下的代碼:

默認的情況下就是將:主配置類(@SpringBootApplication)的所在包及其子包裏邊的組件掃描到Spring容器中。

  • 看完這句話,會不會覺得,這不就是ComponentScan的功能嗎?這倆不就重複了嗎?

我開始也有這個疑問,直到我看到文檔的這句話:

it will be used when scanning for code @Entity classes. It is generally recommended that you place EnableAutoConfiguration (if you’re not using @SpringBootApplication) in a root package so that all sub-packages and classes can be searched.

比如說,你用了Spring Data JPA,可能會在實體類上寫@Entity註解。這個@Entity註解由@AutoConfigurationPackage掃描並加載,而我們平時開發用的@Controller/@Service/@Component/@Repository這些註解是由ComponentScan來掃描並加載的。

  • 簡單理解:這二者掃描的對象是不一樣的。

1.2.2回到Import

我們發現它使用了 Spring 框架提供的 @Import 註解注入了註冊 Bean 的配置類,在往下分析前,不妨先了解一下這個 @Import 註解,在我們平時使用 Spring 框架的 Enable* 類註解時,發現它們都有一個共同的特點,就是都有一個 @Import 註解,用來導入配置類,這些配置方式又分爲三種類型:

  • 直接導入配置類:@Import({xxxConfiguration.class})
  • 依據條件選擇配置類:@Import({xxxSelector.class})
  • 動態註冊 Bean:@Import({xxxRegistrar.class})

我們回到@Import(AutoConfigurationPackages.Registrar.class)這句代碼上,再點進去AutoConfigurationPackages.Registrar.class看看具體的實現是什麼:

	/**
	 * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
	 * configuration.
	 */
	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata,
				BeanDefinitionRegistry registry) {
			register(registry, new PackageImport(metadata).getPackageName());
		}

		@Override
		public Set<Object> determineImports(AnnotationMetadata metadata) {
			return Collections.singleton(new PackageImport(metadata));
		}

	}

1.3總結

@SpringBootApplication等同於下面三個註解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是關鍵(啓用自動配置),內部實際上就去加載META-INF/spring.factories文件的信息,然後篩選出以EnableAutoConfiguration爲key的數據,加載到IOC容器中,實現自動配置功能!

參考: https://blog.csdn.net/zchdjb/article/details/90795633

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章