SpringBoot自动配置

目录

SpringBoot自动配置

SpringBoot自动配置-AutoConfiguration

  • 指基于引入的jar包 对SpringBoot应用进行自动配置
    (自动进行Bean的配置 省去了使用Spring框架时在xml中配置Bean这一步)

  • 为SpringBoot框架的开箱即用提供了基础支撑

配置类-ConfigurationClass

  • 广义的: 被注解@Component直接或间接修饰的某个类 即我们常说的Spring组件

    被@Component修饰的类本身作为Bean

  • 狭义的: 被注解@Configuration所修饰的某个类 又称@Configuration类

    被@Configuration修饰的类本身和其中被@Bean修饰的方法的返回值作为Bean

SpringBoot自动配置的例子

如自动配置redis

  1. 引入依赖

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 配置redis服务器

    spring:
      redis:
        database: 0
        host: 127.0.0.1
        port: 6379
        password: 123456
    
    
  3. 直接使用RedisTemplate

    @Autowired
    private RedisTemplate redisTemplate;
    

整个过程中 我们没有通过任何操作在applicationContext中注册RedisTemplate 这个Bean

SpringBoot启动流程

从SpringApplication.run(…)开始:

  1. 创建一个ApplicationContext实例 即创建ioc容器

  2. 注册主类到ioc容器中(简单但重要的一步)

    被@SpringBootApplication所修饰的类
    一般为main方法所在的类
    这个类将作为遍历配置类的起点

  3. 递归加载并处理所有的配置类

    SpringBoot自动找到所有的配置类
    然后加载和处理他们

  4. 实例化所有的单例Bean

    实例化所有的单例Bean
    依赖注入和自动装配就属于其中的环节

  5. 如果是web应用 启动一个web服务器

步骤3-加载并处理所有的配置类

在这里插入图片描述

  1. SpringBoot首先处理朱磊的@ComponentScan注解

    扫描指定的package 得到一系列的配置类

    包括@Component修饰的 @Configuration修饰的类

    如果在这些扫描得到的配置类上存在@ComponentScan 则递归处理

    以此步骤加载所有的程序中定义的配置类

  2. 处理注解@Import

    根据Import注解的处理结果 可以得到一系列被导入的配置类

    如果此步骤中得到的配置类上依然存在@Import注解 也是通过递归处理的

  3. 处理被@Bean修饰的方法

  4. 处理@Import导入的ImportBeanDefinitionRegistrar

  5. 加入到一个全局的配置类集合中
    在这里插入图片描述

通过递归遍历 SpringBoot发现了所有的配置类

对配置类进行解析处理 并将得到的BeanDefinition注册到ioc容器中

@ComponentScan注解

  • 对指定的package进行扫描 找到其中符合条件的类

  • 默认是搜索被注解@Component修饰的配置类 (包括直接修饰的和间接修饰的)

  • 通过属性basePackages或basePackageClasses来指定要进行扫描的package

  • 如果未指定package 则默认扫描当前@ComponentScan所修饰的类所在的package

@Import注解

  • 提供了一种显示的 从其他地方加载配置类的方式 用于避免使用性能较差的组件扫描(Component Scan)

  • 支持导入:

    • 普通类(非后面所说两个接口的实现类)

    • 接口importSelector的实现类

    • 接口importBeanDefinitionRegistrar的实现类

import导入普通类例子

注意此处ConfigA没有被@Component直接或间接的修饰
在这里插入图片描述

在这里插入图片描述

导入ImportSelector接口的实现类例子

可以通过@import导入一个ImportSelector实现类

ImportSelector接口中的selectImports方法

他的返回值是一个字符串数组

数组中的每一个元素都代表一个将被导入的配置类的全限定名

利用这一特性 我们可以给ioc容器动态的导入多个配置类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

导入接口ImportBeanDefinitionRegistrar实现类例子

在ImportBeanDefinitionRegistrar的实现类中

可以手动向registry(可以理解为目标ioc容器)中注册多个Bean定义

从而实现个性化定制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结-SpringBoot加载配置类的方式

  • 使用注解@ComponentScan

  • 使用注解@Import

    • 导入普通类

    • 导入选择器ImportSelector

    • 导入注册器 ImportBeanDefinitionRegistrar

实现自动配置的方式

如果@ComponentScan实现

通过包扫描向ioc容器中注册第三方jar包中定义的Bean

需要记住每个第三方jar包中需要被扫描的包的名称

然后在程序中进行扫描包

性能较差 使用不便 不符合SpringBoot开箱即用的理念

如果使用@Import导入普通类实现

需要记住具体的类名

虽然性能相比包扫描ComponentScan好

但依然使用不便

如果使用@Import导入注册器ImportBeanDefinitionRegistrar实现

ImportBeanDefinitionRegistrar导入的不是Bean

而是BeanDefinition

是针对@Bean方法的补充

用于实现自动配置并不恰当

(不理解…)

如果使用@Import导入选择器ImportSelector

SpringBoot实现自动配置使用的方式

@SpringBootApplicaton被@EnableAutoConfiguration注解修饰

@EnableAutoConfiguration注解被@Import(AutoConfigurationImportSelector.class)修饰

SpringBoot通过@Import(AutoConfigurationImportSelector.class)来实现自动配置

@SpringBootApplication注解结构

在这里插入图片描述
@SpringBootApplication注解结构图

  • @SpringBootApplication修饰的类 会被@Configuration间接修饰 即"源配置类"

  • SpringBoot框架会对"源配置类"所在的package进行组件扫描(ComponentScan)

  • SpringBoot通过@Import(AutoConfigurationImportSelector.class)来实现自动配置

SpringBoot自动装配的原理

如何实现AutoConfigurationImportSelector

"开箱即用"即用户只需要引入jar包即可

不需要关心jar包中有哪些自动装配类

类名是什么 所在的包名是什么 都不需要用户关心

SpringBoot采用SpringFactories机制实现这一点

  • javaSPI机制的延申和扩展

  • SpringFactories是javaSPI设计思想的延申和扩展

  • SpringBoot基于它来实现的自动配置功能

SpringFactories机制

核心逻辑为:

从classpath中读取到所有jar包中的配置文件META-IF/spring.factories

然后根据指定的key从配置文件中解析出对应的value

AutoConfigurationImportSelector

在AutoConfigurationImportSelector的selectImports方法中:

  1. 通过SpringFactories机制加载配置文件

    通过ClassLoader去获取classpath中的配置文件META-INF/spring.factories

  2. 找出所有的自动配置类

    在所有的配置文件META-INF/spring.factories中

    筛选出以EnableAutoConfiguration.class为key的 符合条件的配置类
    (spring.factories内容格式为:“key=value1,value2,…valueN”)

  3. 根据@Conditional过滤掉不必要的自动装配类

    @Conditional 提供了配置过滤机制

    在特定条件满足时才会向ioc容器注册指定组件

    可以理解为一种特殊的if语句(待补充)

SpringFactories机制对比JavaSPI机制

  • 相同的:

    • 都要求第三方jar包提供配置文件

    • 都使用ClassLoader.getResource(…)读取配置文件

  • 不同的

    • 约定的配置文件路径不同

      • SpringFactories机制:
        META-IF/spring.factories

      • JavaSPI机制:
        META-IF/services/<Service接口的全限定名>

    • 配置文件内容不同

      • SpringFactories机制:
        内容格式为:“key=value1,value2,…valueN”

      • JavaSPI机制:
        内容格式是serviceProvider的类全限定名
        多个Provider类的话每个类名占据一行

    • loader类不同

      • SpringFactories机制:
        通过类SpringFactoriesLoader返回一个类名的集合
        可以根据需求对这些类名进行下一步处理

      • JavaSPI机制:
        返回一个ServiceProvider的对象实例集合

示意图

在这里插入图片描述

总结

SpringBoot实现bean自动配置

需要获知 在第三方jar包中 那些类是需要被配置的bean

只要能够获知这一点 就可以与配置程序中自定义bean相同的方式来处理这些类

获知这一点是使用了一种类似JavaSPI机制的方式:SpringFactories机制

SpringBoot在启动时 读取classpath下的所有spring.factories文件

从key为EnableAutoConfiguration.class的value中获取到所有需要进行自动配置的类的全限定名

至此 springBoot获取了实现自动配置需要的所有信息

此文章为https://www.bilibili.com/video/BV1NY411P7VX/?spm_id_from=333.788&vd_source=e974e5b422b5e93d638b7ac74272a918视频的学习笔记
感谢原内容作者码场安员外

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值