天天看點

Spring Boot 自動配置 源碼分析

Spring Boot 最大的特點(亮點)就是自動配置 AutoConfiguration

下面,先說一下 @EnableAutoConfiguration ,然後再看源代碼,到底自動配置是怎麼配置的

1.  @EnableAutoConfiguration

Spring Boot 自動配置 源碼分析

@SpringBootApplication是一個複合注解,本節我們重點關注 @EnableAutoConfiguration

Spring Boot 自動配置 源碼分析

自動配置類是正常的Spring @Configuration bean。它們使用SpringFactoriesLoader機制定位。通常,自動配置bean是@Conditional Bean(最經常使用@ConditionalOnClass和@ConditionalOnMissingBean注解)

在@EnableAutoConfiguration注解上有一個@Import注解

@Import這個注解表明要導入的一個或多個元件類,通常是@Configuration類。

@Import注解提供與Spring XML中的<import />元素等效的功能。允許導入@Configuration類,ImportSelector和ImportBeanDefinitionRegistrar實作以及正常元件類。

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

根據導入的@Configuration類的AnnotationMetadata,傳回AutoConfigurationImportSelector.AutoConfigurationEntry。

方法的參數AnnotationMetadata代表配置類上的注解中繼資料,方法的傳回值是應該被導入的自動配置類

首先,擷取配置類上的注解的屬性

Spring Boot 自動配置 源碼分析

又是熟悉的方法:SpringFactoriesLoader.loadFactoryNames() 

Spring Boot 自動配置 源碼分析

在所有 META-INF/spring.factories 檔案中查找 org.springframework.boot.autoconfigure.EnableAutoConfiguration

Spring Boot 自動配置 源碼分析

然後,去重

Spring Boot 自動配置 源碼分析

然後,再排除一些,根據注解屬性中明确指定的exclude

Spring Boot 自動配置 源碼分析

删除所有需要排除的

然後,過濾掉一些不需要的

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

根據對所有的需要自動配置的類應用那三個過濾器

最終剩下的就是真正需要導入的,或者說真正需要自動配置的

在衆多需要自動配置的類中,我們挑一個熟悉的來看一下,就挑org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

Spring Boot 自動配置 源碼分析

看這注解,當classpath中有RedisOperations時才會自動配置該類,當有RedisConnectionFactory且沒有redisTemplate時才會建立一個redisTemplate,同理,有RedisConnectionFactory且沒有stringRedisTemplate時才會建立一個stringRedisTemplate

回顧一下

1、在所有 META-INF/spring.factories 檔案中查找 org.springframework.boot.autoconfigure.EnableAutoConfiguration,傳回一個List<String>

2、對上一步傳回的List去重

3、根據注解exclude屬性排除List中的一些元素

4、根據AutoConfigurationImportFilter過濾掉一些不需要自動配置的元素

5、講過以上四步,List中剩下的元素就是最終需要自動配置的元素(類)

至此,隻是篩選出了哪些類需要自動配置,但還沒有真正裝配(執行個體化),真正執行個體化Bean是在Spring Boot啟動時重新整理ApplicationContext時做的

注解隻是個标記,是給反射用的,有注解必然有處理它的類

接下來,分析源碼,看看究竟什麼時候開始真正自動裝配

2.  Spring Boot 自動配置源碼分析

Spring Boot 自動配置 源碼分析

又來到了熟悉的SpringApplication.run()方法這裡,這一次,重點看其中的三步:createApplicationContext()、prepareContext() 和 refreshContext()

首先看createApplicationContext()

Spring Boot 自動配置 源碼分析

看看AnnotationConfigServletWebServerApplicationContext有多複雜

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

建立了兩個BeanDefinition分别是AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner,它們都是用來查找并加載Bean定義的,隻是方式不同而已

下面重點看一下AnnotatedBeanDefinitionReader

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

(PS:其實,這裡注冊了很多BeanPostProcessor,有處理Autowired的AutowiredAnnotationBeanPostProcessor,由于本節主要講自動配置的,是以我們重點關注ConfigurationClassPostProcessor)

先做個筆記:

1、ApplicationContext 是 AnnotationConfigServletWebServerApplicationContext

2、構造了一個AnnotatedBeanDefinitionReader,大家要明白BeanDefinitionReader是用來加載Bean定義的

3、把這個AnnotatedBeanDefinitionReader注冊(關聯)到該ApplicationContext

4、在構造AnnotatedBeanDefinitionReader的時候注冊了很多Processors

可見AnnotatedBeanDefinitionReader真的是相當相當重要,而重中之重是org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors()

我們單獨把這段拿出來再看一下

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

如果沒有這個BeanDefinition的時候就添加一個

CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 對應的是 ConfigurationClassPostProcessor

先記住這一點,後面會用到

接下來,看prepareContext()

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

重點看SharedMetadataReaderFactoryContextInitializer

Spring Boot 自動配置 源碼分析

好,記住這一點,此處添加了一個BeanFactoryPostProcessor,它是一個CachingMetadataReaderFactoryPostProcessor

最後,再來看refreshContext()

調用是Spring的refresh()

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

重點看 invokeBeanFactoryPostProcessors 調用所有已注冊的BeanPostProcessor

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

這裡,調用getBeanFactoryPostProcessors()傳回的BeanFactoryPostProcessors中有CachingMetadataReaderFactoryPostProcessor

好,記住這一點

繼續看PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()

Spring Boot 自動配置 源碼分析

好,看CachingMetadataReaderFactoryPostProcessor#postProcessBeanDefinitionRegistry()

Spring Boot 自動配置 源碼分析

又看到了熟悉的AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,我們知道它是ConfigurationClassPostProcessor

回到PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()繼續往下看

Spring Boot 自動配置 源碼分析

得到ConfigurationClassPostProcessor

接下來,調用postProcessBeanDefinitionRegistry

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

方法太長,就不截全圖了,總之就是找到配置類,開始解析配置類了,隻看重點

到這裡終于和我們前面講的@EnableAutoConfiguration自動配置開始沾點兒邊了

Spring Boot 自動配置 源碼分析
Spring Boot 自動配置 源碼分析

下面,重點來了,核心中的核心

Spring Boot 自動配置 源碼分析

終于寫完了,累死我了