Spring Boot自动配置原理、实战、手撕自动装配源码

一、Spring Boot自动配置原理

相比较于传统的 Spring 应用,搭建一个 SpringBoot 应用,我们只需要引入一个注解 @SpringBootApplication,就可以成功运行。

前面四个不用说,是定义一个注解所必须的,关键就在于后面三个注解:

当然如果你想了解前面四个注解,可以查看我的文章:

@Target、@Retention、@Documented、@Inherited注解的超详细分析

@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。也就是说我们如果不用 @SpringBootApplication 这个复合注解,而是直接使用最下面这三个注解,也能启动一个 SpringBoot 应用。

前面四个不用说,是定义一个注解所必须的,关键就在于后面三个注解:@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。也就是说我们如果不用 @SpringBootApplication 这个复合注解,而是直接使用最下面这三个注解,也能启动一个 SpringBoot 应用,其中,Spring Boot的自动配置最核心的注解是@EnableAutoConfiguration。

1.@SpringBootConfiguration 注解


这个注解我们点进去就可以发现,它实际上就是一个 @Configuration 注解,这个注解大家应该很熟悉了,加上这个注解就是为了让当前类作为一个配置类交由 Spring 的 IOC 容器进行管理,因为前面我们说了,SpringBoot 本质上还是 Spring,所以原属于 Spring 的注解 @Configuration 在 SpringBoot 中也可以直接应用。

2.@ComponentScan 注解


@ComponentScan这个注解也很熟悉,用于定义 Spring 的扫描路径,等价于在 xml 文件中配置 context:component-scan,假如不配置扫描路径,那么 Spring 就会默认扫描当前类所在的包及其子包中的所有标注了 @Component,@Service,@Controller 等注解的类。

通过查看源码可以知道,@ComponentScan使用了@Repeatable(ComponentScans.class)注解,@ComponentScans是聚合多个ComponentScan注解的容器注解,它使ComponentScan注解可以在同一个类或方法上多次使用,@Repeatable注解的例子如下:

3.@EnableAutoConfiguration注解

这个注解才是实现自动装配的关键,点进去之后发现,它是一个由 @AutoConfigurationPackage 和 @Import 注解组成的复合注解

1)@AutoConfigurationPackage

①@import注解简介

@Import 注解,通常用于配置类(Configuration类)中,用于导入其他配置类或组件。

@Import 的主要用途是引入其他的配置类或将其他类注册为Spring容器中的组件。这可以帮助在Spring应用程序中构建模块化的配置,并将多个配置类组合在一起以构建完整的应用程序上下文。

@Import 可以使用不同的参数来指定要导入的配置类或要注册为组件的类,具体取决于使用的具体注解,例如:

  1. @Import(ClassToImport.class): 导入一个指定的类作为配置类或组件。

  2. @Import({Class1.class, Class2.class}): 导入多个类作为配置类或组件。

  3. @Import(MyImportSelector.class): 使用一个实现了ImportSelector接口的类,根据条件动态选择要导入的配置类。

  4. @Import(MyImportBeanDefinitionRegistrar.class): 使用一个实现了ImportBeanDefinitionRegistrar接口的类,允许自定义注册bean的逻辑。

这些方式允许你以不同的方式组合和导入配置类或组件,以满足应用程序的需求。@Import通常与Spring的注解驱动配置一起使用,例如@Configuration@ComponentScan,以更好地管理应用程序的组件和配置。

②@Import(AutoConfigurationPackages.Registrar.class)

@Import(AutoConfigurationPackages.Registrar.class) 用于导入 AutoConfigurationPackages.Registrar 这个类。这通常用于自动配置类(Auto-Configuration classes)中,以确保能够扫描到与自动配置相关的包。

使用AutoConfigurationPackages这个类注册程序包。如果没有指定基包或基包类,则会注册带注解类的包。

具体来说,AutoConfigurationPackages.Registrar 是Spring Boot内部使用的一个类,它的作用是将与自动配置相关的包注册到Spring应用程序的包扫描路径中。这样,Spring框架可以找到并加载与这些包相关的组件和配置。

在Spring Boot中,自动配置类通常包含在spring.factories文件中,这些自动配置类负责自动配置应用程序的各个部分。为了确保这些自动配置类能够被发现并生效,@Import(AutoConfigurationPackages.Registrar.class) 通常用于这些自动配置类中。

具体地,AutoConfigurationPackages.Registrar 会注册自动配置类所在的包,以便Spring可以扫描和加载这些类。这有助于确保自动配置的生效,并使Spring Boot应用程序能够自动配置其所需的功能。

通常情况下,开发者无需显式使用 @Import(AutoConfigurationPackages.Registrar.class),它是在Spring Boot的自动配置机制内部使用的。但如果你需要编写自定义的自动配置类,你可能需要了解它的作用以正确配置包扫描路径。

2)@Import(AutoConfigurationImportSelector.class)

@Import(AutoConfigurationImportSelector.class) 用于自动配置类(Auto-Configuration classes)中,以根据条件自动导入其他配置类。它是Spring Boot自动配置机制的一部分,用于根据应用程序的环境和配置来动态选择和导入适当的配置类。

具体来说,AutoConfigurationImportSelector 是一个选择器,它根据应用程序的条件和配置来选择需要导入的自动配置类。这些自动配置类包含了应用程序所需的配置,以便自动配置各个部分。

在Spring Boot应用程序中,通常不需要显式使用 @Import(AutoConfigurationImportSelector.class),因为它是在内部由Spring Boot自动处理的。Spring Boot会自动根据应用程序的配置和依赖关系,选择并导入合适的自动配置类,以确保应用程序能够自动配置所需的功能。

总结起来,@Import(AutoConfigurationImportSelector.class) 是Spring Boot内部机制的一部分,用于根据应用程序的条件和配置来选择和导入自动配置类,以满足应用程序的需求。通常情况下,开发者无需手动使用此注解,Spring Boot会自动处理自动配置。

①AutoConfigurationImportSelector.class的selectImports方法

这个类代码挺多的,我这边只写一下里面重要的方法

selectImports方法会扫描类路径并找到所有的自动配置类。然后,对每个自动配置类,selectImports 方法会被调用,以确定是否要导入这个自动配置类。如果满足条件,该自动配置类的名称会被返回。

这个方法返回的是一个字符串数组,其中包含了要导入的自动配置类的全限定类名。这些自动配置类包含了应用程序所需的配置,以便启用各种功能和特性。

查看源码我们可以看到,selectImports(),方法调用了getAutoConfigurationEntry()方法,这个方法里面又有一个关键的方法getCandidateConfigurations()

getCandidateConfigurations()方法借助SpringFactoriesLoader.loadFactoryNames()方法,扫描了所有包含META-INF/spring.factories的jar包,这些jar包实际上就是我们引入的starter中的依赖。

在loadFactoryNames()方法中加载spring.factories文件。

二、Debug验证

在AutoConfigurationImportSelector类的getCandidateConfigurations()方法的第一行打上断点,然后debug模式启动SpringBoot项目。

我们发现 configurations集合中存储了许多全类名,这些就是SpringBoot帮我们把依赖中的相关的组件装配到了IOC容器中。

比如我们项目中添加了注册中心nacos相关的依赖,可以看到nacos依赖的库中META-INF文件夹中有spring.factories文件,这个文件中定义了一些必要的组件全类名,SpringBoot根据这些就可以利用Java的反射机制为我们创建出这些对象,然后放到IOC容器中。

当然并不是所有依赖的库中的META-INF文件夹中都有spring.factories文件,spring.factories只是 Spring Boot 自动配置的一部分,如果你的项目并不使用这些特性,就不会存在这个文件。

三、总结

SpringBoot自动装配原理:

  1. @EnableAutoConfiguration注解导入AutoConfigurationImportSelector类。

  2. selectImports方法调用SpringFactoriesLoader.loadFactoryNames()扫描所有jar下面的对应的META-INF/spring.factories文件.

  3. 把所有在spring.factories文件中扫描到的全类名进行实例化加载到IOC容器中。

SpringBoot自动装配说白了就是自动帮我们把第三方的组件装配到IOC容器,不需要再手动的去写Bean相关的配置,因为大多数配置SpringBoot已经帮我们约定好了,也就是约定大于配置的理念。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穗余

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值