【框架源码】SpringBoot核心源码解读之自动配置源码分析

简介: 【框架源码】SpringBoot核心源码解读之自动配置源码分析

SpringBoot流行之前,程序员大多是用SSM框架整合来进行WEB后端开发。这种方式非常麻烦,需要手动引入大量的包,还要配置很多XML文件,光是搭建环境就需要很久。

基于这种的SSM中xml配置的繁琐,后来衍生出SpringBoot。SpringBoot中的自动装载,大大简化了开发者对于配置的相关信息。

问题:什么是SpringBoot自动配置

  • 当spring容器启动后,一些自动配置类通过@Conditional注解自动装配的IOC容器中
  • 不需要手动去注入,简化了开发,省去了繁琐的配置
  • 自动配置的相关工作就在 @SpringBootApplication这个注解上

我们来看一下@SpringBootApplication这个注解。

@Target({ElementType.TYPE})  //注解的作用范围,用在类,接口,注解等上面
@Retention(RetentionPolicy.RUNTIME) //注解生命周期,runtime,保留在运行时期
@Documented //可以被文档化
@Inherited //可以被子类继承
@SpringBootConfiguration  //里面是@Configuration属于配置类
@EnableAutoConfiguration  //启动自动配置功能
//配置扫描包
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication

@SpringBootApplication 是一个复合注解,由几个核心的注解组成。

  • @SpringBootConfiguration
  • 里面是 @Configuration,代表是一个配置类,说明主程序类也是一个配置类
  • @EnableAutoConfiguration
  • @AutoConfigurationPackage 将指定的一个包下的所有组件导入到容器当中
  • 在@AutoConfigurationPackage 注解中存在一个 @Import({Registrar.class}) 注解,自动配置包就是通过这个完成的。
  • @ComponentScan
  • 指定扫描哪些组件,默认是扫描主程序所在的包以及其子包
  • 它的核心在于@EnableAutoConfiguration这个注解,这里面是加载自动配置的类信息。

@EnableAutoConfiguration注解核心内容

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage //自动配置包
@Import(AutoConfigurationImportSelector.class) //通过import导入满足条件的bean,并加载到spring的ioc容器里面
public @interface EnableAutoConfiguration 

@AutoConfigurationPackage注解核心内容

  • Registrar的作用是扫描包,默认是把主类所在的包和子包里面全部类扫描进容器里面
  • 所以为什么开发springboot项目需要把主类放到最外层目录,不然就对的注解类就找不到
@Import(AutoConfigurationPackages.Registrar.class) //把Registrar导入到spring容器里面

核心逻辑为这段逻辑,一会我们会断点进行调试。

    //获取主程序所在的目录为位置,metadata是元注解信息
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata,
        BeanDefinitionRegistry registry) {
      register(registry, new PackageImport(metadata).getPackageName());
    }

下面,我们来看一下@Import(AutoConfigurationImportSelector.class)这个里面都做了哪些操作。其核心就是通过import导入满足条件的bean, 把springboot应用里面符合@Configuration的类,加载到spring的ioc容器里面

  //用于实现动态注册Bean的功能,【批量】导入对象到容器里,根据条件动态地选择需要注册的Bean,并加入Spring容器
  //实现ImportSelector接口,这个接口的selectImports方法会返回一个String数组,数组中的值就是要添加的组件的全类名
  public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
      return NO_IMPORTS;
    }
    //加载元数据信息
    AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
        .loadMetadata(this.beanClassLoader);
    //获取需要自动装载的类的信息
    AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
        autoConfigurationMetadata, annotationMetadata);
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
  }

ok,我们再来看一下getAutoConfigurationEntry()这个方法的逻辑。这个方法主要是根据指定的注解元数据获取自动配置的条目。

protected AutoConfigurationEntry getAutoConfigurationEntry(
      AutoConfigurationMetadata autoConfigurationMetadata,
      AnnotationMetadata annotationMetadata) {
    //判断是否启用了自动配置
    if (!isEnabled(annotationMetadata)) {
      return EMPTY_ENTRY;
    }
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    //获取候选自动配置类列表
    List<String> configurations = getCandidateConfigurations(annotationMetadata,
        attributes);
    //去除重复的自动配置类
    configurations = removeDuplicates(configurations);
    //获取需要排除的自动配置类列表
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    //检查是否存在需要排除的自动配置类
    checkExcludedClasses(configurations, exclusions);
    //将需要排除的类从自动配置类列表中移除
    configurations.removeAll(exclusions);
    //获取配置类过滤器,对候选自动配置类列表进行过滤
    configurations = filter(configurations, autoConfigurationMetadata);
    //触发自动配置导入事件,并返回一个新的自动配置条目
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationEntry(configurations, exclusions);
  }

我们来看看getCandidateConfigurations()这里面核心逻辑就是去META-INF/spring.factories这个文件中去拉取全部的配置信息。

  protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
      AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
        getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
    Assert.notEmpty(configurations,
        "No auto configuration classes found in META-INF/spring.factories. If you "
            + "are using a custom packaging, make sure that file is correct.");
    return configurations;
  }
  public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

好的,接下来我们来调试走下源码流程。

a1f8bffd3e694ef3a37988a696dc9a28.jpg

987c568e8fb74e5d89d7b7aa24ca3c46.jpg

0262e2ac3d3f4bf196a98d85b29d1885.jpg

32e9efa28ee5450f82ca0f46d5c2a752.jpg


9fe6a8b9fcba4a8296584e3b54f1c8a3.jpg

2daf7353fbbe44a7bbbd069f3e7b3ec9.jpg


49d6b3f546f74d5bbe6ebccbd652033e.jpg


ca5fa536f36449209b0b840a7c48383e.jpg

0b8c6fc7fe9f45df8f5def188fab3c6b.jpg

c6659135d6a042e5a5496e46a6e14bbe.jpg

2400ac1c88f342efb4b2558a1967ccb8.jpg

4e027a709d5549bfa75f876683cc5e3b.jpg

ok,我们来总结一下,SpringBoot自动装载的全流程。


首先,加载一下元数据信息

获取需要自动装载的类的信息

判断是否启用了自动配置

获取候选自动配置类列表

获取需要排除的自动配置类列表

检查是否存在需要排除的自动配置类

将需要排除的类从自动配置类列表中移除

获取配置类过滤器,对候选自动配置类列表进行过滤

触发自动配置导入事件,并返回一个新的自动配置条目

注册Bean的定义列表


目录
打赏
0
1
0
0
61
分享
相关文章
SpringBoot框架
Spring Boot 是 Spring 家族中最流行的框架,旨在简化 Spring 应用的初始搭建与开发。它通过自动配置、起步依赖和内嵌服务器三大核心功能,大幅减少配置复杂度,提升开发效率。开发者可快速构建独立运行的 Web 应用,并支持多种数据访问技术和第三方集成。
基于 Spring Boot 框架开发 REST API 接口实践指南
本文详解基于Spring Boot 3.x构建REST API的完整开发流程,涵盖环境搭建、领域建模、响应式编程、安全控制、容器化部署及性能优化等关键环节,助力开发者打造高效稳定的后端服务。
98 1
|
2天前
|
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 &gt; Java系统属性 &gt; application.properties &gt; application.yml &gt; application.yaml。
25 0
SpringBoot框架常见的starter你都用过哪些 ?
本节介绍常见的Spring Boot Starter,分为官方(如Web、AOP、Redis等)与第三方(如MyBatis、MyBatis Plus)两类,用于快速集成Web开发、数据库、消息队列等功能。
20 0
|
2天前
|
聊聊你对SpringBoot框架的理解 ?
SpringBoot是Spring家族中流行的子项目,旨在简化Spring框架开发的繁琐配置。它主要提供三大功能:starter起步依赖简化依赖管理,自动配置根据条件创建Bean,以及内嵌Web服务器支持Jar包运行,极大提升了开发效率。
24 0
第五章 Spring框架
第五章 Spring框架
|
5天前
|
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
26 0
Spring Boot 框架深入学习示例教程详解
本教程深入讲解Spring Boot框架,先介绍其基础概念与优势,如自动配置、独立运行等。通过搭建项目、配置数据库等步骤展示技术方案,并结合RESTful API开发实例帮助学习。内容涵盖环境搭建、核心组件应用(Spring MVC、Spring Data JPA、Spring Security)及示例项目——在线书店系统,助你掌握Spring Boot开发全流程。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
120 1

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问