SpringBoot核心要素:自动配置

282 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情

1、SpringBoot自动配置

自动配置可以说是SpringBoot最核心的一个要素,也是不同于Spring的一个最明显的标志;对于SpringBoot自动配置原理的学习通常一遍是不够的,需要反复的多看几遍才能够更好地理解SpringBoot自动配置,本文介绍了SpringBoot的自动配置原理;适合帮助新手学习SpringBoot的自动配置原理,降低学习难度;也适合学习过自动配置原理的老手,可以再看一遍本文,温故而知新;

1.1、SpringBoot自动配置的概念

什么是SpringBoot的自动配置?

SpringBoot 自动配置,英文是 Auto-Configuration:

  • 它是指基于你引入的依赖Jar 包,对 SpringBoot 应用进行自动配置;
  • 它为SpringBoot框架的“开箱即用”提供了基础支撑;

术语“配置类”英文 Configuration Class

  • 广义的“配置类”被注解 @Component直接或间接修饰的某个类即我们常说的 Spring 组件,其中包括了 @Configuration 类;
  • 狭义的“配置类特指被注解@Configuration 所修饰的某个类又称为 @Configuration 类;

通常说的配置类就是广义的配置类,狭义的配置类通常说@Configuration类。

配置类示例:

SpringBoot自动配置实例——Redis自动配置

1、引入依赖

2、配置Redis服务器

3、直接使用RedisTemplate或StringRedisTemplate操作Redis

在Redis的自动配置实例中,只是导入了jar之后,就能够使用RedisTemplate了,这其中就是自动配置机制,SpringBoot将相关的Bean对象注册到了IOC容器中。

1.2、SpringBoot的启动流程(简化版)

SpringBoot的启动流程(简化版)

着重看一下第三步,加载并处理所有的配置类:

递归加载并处理配置类的流程,即parser.parse()方法,即processConfigurationClasses()方法:

展开的递归遍历并处理配置类的过程,通过@ComponentScan和@Import注解,不断地将配置类注册到IOC容器中,如下:

两个重要注解@ComponentScan和@Import:

注解@ComponentScan

@ComponentScan,是来自 Spring 框架的一个注解:

  • 它的作用是对指定的 package 进行扫描,找到其中符合条件的类,默认是搜索被注解@Component 修饰的配置类;
  • 通过属性 basePackages 或 basePackageClasses,来指定要进行扫描的 package;
  • 如果未指定 package,则默认扫描当前 @ComponentScan 所修饰的类所在的 package;

注解@Import

@lmport,是来自Spring 框架的一个注解:

  • 它的作用是提供了一种显式地从其它地方加载配置类的方式这样可以避免使用性能较差的组件扫描(Component Scan);
  • 支持导入
    • 普通类(这里的“普通”,是相对于随后的两个接口而言的) ;
    • 接口 ImportSelector 的实现类;
    • 接口 ImportBeanDefinitionRegistrar 的实现类;

注: 这里的Dog并没有添加@Bean类似注解,此时并没有注册到IOC容器中,在ImportBeanDefinitionRegistrar实现类中才添加到IOC容器中,所以ImportBeanDefinitionRegistrar可以看作是@Bean方法的一个补充。

总结一下SpringBoot加载配置类的方式

  • 使用注解 @ComponentScan;
  • 使用注解 @Import;
    • 导入普通类;
    • 导入选择器 ImportSelector;
    • 导入注册器ImportBeanDefinitionRegistrar;

我们讨论一下:应该使用哪种方式来加载SpringBoot的自动配置类呢?

首先排除注解@ComponentScan 。因为使用它很不方便,开发人员需要记住每个第三方 Jar 包中的package名称,然后把它们写到应用程序中。拜托,程序员的头发本来就不多了!

1.3、SpringBoot自动配置的实现原理

SpringBoot自动配置实现中导入配置类的方式:

1.3.1、SpringBoot自动配置原理解析

如何实现类 AutoConfigurationImportSelector

SpringFactories和Java SPI类似,但SpringFactories要更复杂一点,也更灵活:

类AutoConfigurationImportSelector关键源码:

自动配置的入口方法 getAutoConfigurationEntry():

从资源文件 spring.factories 中获取自动配置类的方法,getCandidateConfigurations():

AutoConfigurationImportSelector实现流程:

注解@Conditional

@Conditional,是来自 Spring 框架的一个注解:

  • 它的作用是实现:只有在特定条件满足时,才会向 loc 容器注册指定的组件;
  • 我们可以将 @Conditional 理解为某种IF 语句;

1.3.2、SpringBoot自动配置原理总结

SpringBoor自动配置实例-Redis

未涉及到的一些知识点

  • 注解 @AutoConfigurationPackage 的作用
  • 注解 @Conditional 的实现原理
  • 如何定义自动配置类的加载顺序
  • 等等...

参考

www.bilibili.com/video/BV1Zu…