SpringBoot自动配置底层原理(手撕@SpringBootApplication注解源码)

简介: SpringBoot自动配置底层原理(手撕@SpringBootApplication注解源码)

在这里插入图片描述
我们从主程序类的@SpringBootApplication注解开始讲起
首先我们点进@SpringBootApplication中:
在这里插入图片描述
看到它是由@Target、@Retention、@Documented、@Inherited四个元注解和@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan()三个注解组合成的注解;
元注解我们就不用多说了,接下来我将讲解@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan这三个注解。
我们先说两个简单的注解@SpringBootConfiguration、@ComponentScan注解,最后再说最核心也最麻烦的注解@EnableAutoConfiguration注解。

一.@SpringBootConfiguration

我们点进@SpringBootConfiguration中:
在这里插入图片描述
我们发现它是由元注解和@Configuration组成,也就是@Configuration注解,那@Configuration是什么呢,它就代表当前是一个配置类。
也就是说明我们的MainApplication主程序类也是一个配置类,只不过它是一个核心配置类。

二.@ComponentScan

@ComponentScan我们都知道它是一个包扫描注解,指定扫描哪些内容。

三.@EnableAutoConfiguration

来了来了,最重要的它终于来了。
言归正传,我们点进@EnableAutoConfiguration注解中:
在这里插入图片描述
发现它是由4个元注解和@AutoConfigurationPackage、@Import({AutoConfigurationImportSelector.class})注解组成。
我们先讲@AutoConfigurationPackage注解,然后再将@Import({AutoConfigurationImportSelector.class})导入的组件的作用。

1.@AutoConfigurationPackage

我们点进@AutoConfigurationPackage注解中:
在这里插入图片描述
发现它实际上也是@Import注解,导入的Registrar是什么呢,我们在点进去看一下:
在这里插入图片描述

发现它有两个方法,实际上Registrar是给容器中批量的注册组件,因为用import一个一个导入太麻烦了,所以写一段代码批量注册;
我们在第一个方法上打上断点,可以看看它到底注册了哪些组件:
在这里插入图片描述
这个方法有两个参数,如下:
在这里插入图片描述
其中AnnotationMetadata是注解的源信息,注解是指@AutoConfigurationPackage,注解的源信息表示这个注解标在哪,它的每一个属性值都是什么,这个注解是@SpringBootApplication里的注解,@SpringBootApplication标在MainApplication主程序类上,所以它实际上也是标在MainApplication主程序类上的。
我们可以在debug时打开metadata查看其信息:
在这里插入图片描述
发现它确实是在主程序类上,然后我们继续讲这个方法,这个方法在这里new了一个PackageImports:
在这里插入图片描述
相当于把我们的注解源信息拿到获取我们的包名,我们可以让它计算一下我们得到的包名是什么:
在这里插入图片描述
在这里插入图片描述
可以看到计算得到了MainApplication主程序类所在的包路径。
我们接着说那个方法,它得到我们的包路径之后,也就是得到了主程序类的包名,然后把这个包名封装到一个数组里面,然后给我们注册到容器中。
也就是说我们的Registrar相当于是把某个包下的所有组件批量的注册进容器中。
@AutoConfigurationPackage小总结:

  • 利用Registrar给容器中导入一系列组件
  • 将MainApplication主程序类所在包下的所有组件导入进来

2.@Import({AutoConfigurationImportSelector.class})

利用selector再来给容器中批量的导入一些组件
我们点进AutoConfigurationImportSelector中:
在这里插入图片描述
我们的selectImports方法返回的数组规定了给容器中要导入哪些组件,而在selectImports方法中又调用了getAutoConfigurationEntry方法,所以呢,我们现在来研究getAutoConfigurationEntry方法,进入getAutoConfigurationEntry方法,给getAutoConfigurationEntry方法体打上断点:
在这里插入图片描述
debug运行,当我们逐条语句运行到获取configurations之后,可以看到configurations有130条:
在这里插入图片描述
点开configurations会发现有130个全类名,说明这130个全类名指定的组件全部是要导入到我们的容器中去的:
在这里插入图片描述
那我们怎么知道这130个是这样子的呢?我们给这个getCandidateConfigurations方法打一个断点,重新debug:
在这里插入图片描述
进入该方法内部,发现它实际上是用Spring的这些工厂加载器来加载一些东西:
在这里插入图片描述
点进SpringFactoriesLoader.loadFactoryNames:
在这里插入图片描述
再点入(List)loadSpringFactories(classLoaderToUse):
在这里插入图片描述
最终利用该方法给我们加载得到所有组件,那从哪里加载得到所有组件呢?
我们给loadSpringFactories方法体打上一个断点,重新debug:
在这里插入图片描述
可以看到它在这里加载了一个资源文件,位置为:META-INF/spring.factories
也就是说默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件;
现在我们看spring-boot-autoconfigure-2.4.1.jar包下的META-INF:
在这里插入图片描述

发现它有spring.factories文件:
在这里插入图片描述
查看其文件内容,其中有一个配置项,org.springframework.boot.autoconfigure.EnableAutoConfiguration:
在这里插入图片描述
从22行到151行整整130行内容:
在这里插入图片描述
这就是我们的130个需要加载的组件,它们全部都在这里,而且全部都在这个配置文件里写死了,也就是说文件里面写死了spring-boot一启动就要给容器中加载的所有配置类。

但是现实情况是这个样子的吗,是真的要把130个组件全部加载进容器中吗?
实际上不是的,我们的SpringBoot有按需开启自动配置项的功能。
虽然我们130个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration,但是最终会按需配置,按照条件装配规则(@Conditional)。
例如我们点进去AopAutoConfiguration中:
在这里插入图片描述

在这里插入图片描述

在这个类中,我们没有导入org.aspectj.weaver中的Advice这个类,所以其内部类AspectJAutoProxyingConfiguratio不会生效:
在这里插入图片描述

目录
相关文章
|
2月前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
37 0
|
2月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
68 0
|
9天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
9天前
|
Java Maven Spring
SpringBoot配置跨模块扫描问题解决方案
在分布式项目中,使用Maven进行多模块开发时,某些模块(如xxx-common)没有启动类。如何将这些模块中的类注册为Spring管理的Bean对象?本文通过案例分析,介绍了两种解决方案:常规方案是通过`@SpringBootApplication(scanBasePackages)`指定扫描路径;推荐方案是保持各模块包结构一致(如com.xxx),利用SpringBoot默认扫描规则自动识别其他模块中的组件,简化配置。
SpringBoot配置跨模块扫描问题解决方案
|
16天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
65 14
|
2月前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
56 1
SpringBoot入门(7)- 配置热部署devtools工具
|
2月前
|
消息中间件 Java 数据库
解密Spring Boot:深入理解条件装配与条件注解
Spring Boot中的条件装配与条件注解提供了强大的工具,使得应用程序可以根据不同的条件动态装配Bean,从而实现灵活的配置和管理。通过合理使用这些条件注解,开发者可以根据实际需求动态调整应用的行为,提升代码的可维护性和可扩展性。希望本文能够帮助你深入理解Spring Boot中的条件装配与条件注解,在实际开发中更好地应用这些功能。
40 2
|
2月前
|
Java 容器
springboot自动配置原理
启动类@SpringbootApplication注解下,有三个关键注解 (1)@springbootConfiguration:表示启动类是一个自动配置类 (2)@CompontScan:扫描启动类所在包外的组件到容器中 (3)@EnableConfigutarion:最关键的一个注解,他拥有两个子注解,其中@AutoConfigurationpackageu会将启动类所在包下的所有组件到容器中,@Import会导入一个自动配置文件选择器,他会去加载META_INF目录下的spring.factories文件,这个文件中存放很大自动配置类的全类名,这些类会根据元注解的装配条件生效,生效
|
2月前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
44 2
|
2月前
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
40 3