Spring Boot 最大的特点(亮点)就是自动配置 AutoConfiguration

下面,先说一下 @EnableAutoConfiguration ,然后再看源代码,到底自动配置是怎么配置的

1.  @EnableAutoConfiguration

@SpringBootApplication是一个复合注解,本节我们重点关注 @EnableAutoConfiguration

自动配置类是常规的Spring @Configuration bean。它们使用SpringFactoriesLoader机制定位。通常,自动配置bean是@Conditional Bean(最经常使用@ConditionalOnClass和@ConditionalOnMissingBean注解)

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

@Import这个注解表明要导入的一个或多个组件类,通常是@Configuration类。

@Import注解提供与Spring XML中的<import />元素等效的功能。允许导入@Configuration类,ImportSelector和ImportBeanDefinitionRegistrar实现以及常规组件类。

根据导入的@Configuration类的AnnotationMetadata,返回AutoConfigurationImportSelector.AutoConfigurationEntry。

方法的参数AnnotationMetadata代表配置类上的注解元数据,方法的返回值是应该被导入的自动配置类

首先,获取配置类上的注解的属性

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

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

然后,去重

然后,再排除一些,根据注解属性中明确指定的exclude

删除所有需要排除的

然后,过滤掉一些不需要的

根据对所有的需要自动配置的类应用那三个过滤器

最终剩下的就是真正需要导入的,或者说真正需要自动配置的

在众多需要自动配置的类中,我们挑一个熟悉的来看一下,就挑org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

看这注解,当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 自动配置源码分析

又来到了熟悉的SpringApplication.run()方法这里,这一次,重点看其中的三步:createApplicationContext()、prepareContext() 和 refreshContext()

首先看createApplicationContext()

看看AnnotationConfigServletWebServerApplicationContext有多复杂

创建了两个BeanDefinition分别是AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner,它们都是用来查找并加载Bean定义的,只是方式不同而已

下面重点看一下AnnotatedBeanDefinitionReader

(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()

我们单独把这段拿出来再看一下

如果没有这个BeanDefinition的时候就添加一个

CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 对应的是 ConfigurationClassPostProcessor

先记住这一点,后面会用到

接下来,看prepareContext()

 

重点看SharedMetadataReaderFactoryContextInitializer

好,记住这一点,此处添加了一个BeanFactoryPostProcessor,它是一个CachingMetadataReaderFactoryPostProcessor

最后,再来看refreshContext()

调用是Spring的refresh()

重点看 invokeBeanFactoryPostProcessors 调用所有已注册的BeanPostProcessor

这里,调用getBeanFactoryPostProcessors()返回的BeanFactoryPostProcessors中有CachingMetadataReaderFactoryPostProcessor

好,记住这一点

继续看PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()

好,看CachingMetadataReaderFactoryPostProcessor#postProcessBeanDefinitionRegistry()

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

回到PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()继续往下看

得到ConfigurationClassPostProcessor

接下来,调用postProcessBeanDefinitionRegistry

方法太长,就不截全图了,总之就是找到配置类,开始解析配置类了,只看重点

到这里终于和我们前面讲的@EnableAutoConfiguration自动配置开始沾点儿边了

下面,重点来了,核心中的核心

终于写完了,累死我了

最新文章

  1. scikit-learn随机森林调参小结
  2. Basic Tutorials of Redis(4) -Set
  3. mingw32 捕获异常的4种方法
  4. sqlserver删除所有表(表结构和数据)
  5. 利用loadrunner代理方式,录制手机APP脚本
  6. (转)AVI文件格式解析+AVI文件解析工具
  7. [Js]滑动门效果
  8. [2014-08-18]初尝 AspNet vNext On Mac
  9. JAVA课程设计 刘舒婷 201521123096
  10. 【转】C# 定时器事件(设置时间间隔,间歇性执行某一函数,控制台程序)
  11. VMware安装CentOS7.5
  12. WebService学习总结(一)——WebService的相关概念
  13. 【矢量绘图工具】Adobe Illustrator (AI) CC 2019 for Mac 23.0
  14. Java笔记(六)列表和队列
  15. python杂记一
  16. Excel文档间的数据替换 ---电脑版APP 自动操作魔法师
  17. ANDROID开机动画分析
  18. asp.net cookie的操作
  19. windows10下R配置Rstdio,怎么处理
  20. 基于SSH的网上图书商城-JavaWeb项目-有源码

热门文章

  1. SDN总结
  2. codeforces 878A
  3. POJ1273 最大流模板
  4. sql-libs(2) 数字型
  5. Watch the Wifi: Visually Stunning Look at the Digital World Invading Cities (video)
  6. TypeScript &amp; WebAssembly
  7. Web Vitals
  8. HTTP cache in depth
  9. React SSR in Action
  10. regex read once bug