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不会生效:
在这里插入图片描述

目录
相关文章
|
4月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
1754 0
|
6月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1107 0
|
6月前
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 > Java系统属性 > application.properties > application.yml > application.yaml。
1100 0
|
3月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
422 3
|
3月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
514 2
|
4月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
752 5
|
4月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
256 0
探索Spring Boot的@Conditional注解的上下文配置
|
5月前
|
安全 算法 Java
在Spring Boot中应用Jasypt以加密配置信息。
通过以上步骤,可以在Spring Boot应用中有效地利用Jasypt对配置信息进行加密,这样即使配置文件被泄露,其中的敏感信息也不会直接暴露给攻击者。这是一种在不牺牲操作复杂度的情况下提升应用安全性的简便方法。
1166 10
|
6月前
|
前端开发 Java 数据库连接
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
|
6月前
|
人工智能 安全 Java
Spring Boot yml 配置敏感信息加密
本文介绍了如何在 Spring Boot 项目中使用 Jasypt 实现配置文件加密,包含添加依赖、配置密钥、生成加密值、在配置中使用加密值及验证步骤,并提供了注意事项,确保敏感信息的安全管理。
1336 1