zoukankan      html  css  js  c++  java
  • Spring Boot 自动配置 源码分析

    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自动配置开始沾点儿边了

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

    终于写完了,累死我了

  • 相关阅读:
    http请求需要了解的一些信息
    mac修改终端配色方案
    SpringBoot之使用Redisson实现分布式锁
    https://coding.m.imooc.com/classindex.html?cid=402
    构建微电影
    一个开源的后台管理项目
    mysql
    redis安装
    maven 安装
    Django2.1集成xadmin管理后台所遇到的错误集锦,解决填坑
  • 原文地址:https://www.cnblogs.com/cjsblog/p/14530818.html
Copyright © 2011-2022 走看看