看看SpringBoot的自动装配原理

embedded/2024/9/24 7:31:29/

SpringBoot的自动装配原理

明天面试浅浅复习一下八股文

面试官:说一下springboot的自动装配

像以前开发的时候,配置文件需要用xml和java配置类进行显式配置,一整就整一大堆的配置文件

then 什么是自动装配?

Spring boot 定义了一套自己的规范,在Spring Boot启动的时候会扫描有什么外部的jar包的META-INF/spring.factories,然后加载里面的配置文件到Spring里面,像那些自己写的starter就只需要按照Spring boot定的规则定义文件就行了。

简单理解就是自动装配就是通过一些注解和一些简单的配置就可以在Spring boot中使用第三方的某些功能。

如何实现自动装配?

自动装配的核心就是@SpringBootApplication

打开这个类look look,这个版本是3.x的SpringBoot

更新太快了,刚刚才开始摸两下java11,3.x的spirng就需要java17只吃了,卷烂了卷烂了

SpringBootApplication.java

java">@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration // 这个在下面再拉出来拷打一下
@EnableAutoConfiguration // 这个注解用来启动自动装配,下面展开
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) // 这个玩意就是扫包的,扫描那些有标注@Component的包,通过定义不扫什么包,比如这个excludeFilters玩意就是用来定义不扫什么包的
public @interface SpringBootApplication

@SpringBootConfiguration

java">Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 注明这个也是个配置类
@Indexed // 作为元注解声明注解,可以减少应用启动的速度,下面稍微展开一下
public @interface SpringBootConfiguration {@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}

@Indexed:当Spring Boot需要扫描的类太多的时候,@ComponentScan就是这个类需要扫描的类太多的时候,应用启动的时间就会变长。这个注解的用处就是用来解决这个问题的,再项目进行编译打包的时候,会自动生成被@Indexed注释的类的解析结果的文件META-INF/spring.components,当Spring开始进行上下文扫描的的时候,会直接读取被@Indexed处理的文件而不需要进行扫描,这样就可以减少应用的启动时间。

@EnableAutoConfiguration:实现自动装配的核心注解

java">@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // 将main包下面的包注册到容器中
@Import(AutoConfigurationImportSelector.class) // 加载需要自动装配的类
public @interface EnableAutoConfiguration {/*** Environment property that can be used to override when auto-configuration is* enabled.*/String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";/*** Exclude specific auto-configuration classes such that they will never be applied.* @return the classes to exclude*/Class<?>[] exclude() default {};/*** Exclude specific auto-configuration class names such that they will never be* applied.* @return the class names to exclude* @since 1.3.0*/String[] excludeName() default {};}

还需要继续深入看看这个AutoConfigurationImportSelector.class

java">// 继承体系
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered // DeferredImportSelector 这个玩意继承了一个叫 ImportSelector的接口
public interface DeferredImportSelector extends ImportSelector // 然后我们现在回到AutoConfigurationImportSelector这个类中,有点混乱了写的
public String[] selectImports(AnnotationMetadata annotationMetadata) {// 判断自动装配是否打开,简单的理解为上面的EnableAutoConfiguration注解if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {// 然后获取需要装配的bean,这个this.getAutoConfigurationEntry是主要负责加载自动配置类的,主要就是获取所有的自动装配的类,然后从上面也有提过的`META-INF/spring.factories`来加载配置类AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}

这个方法主要是读取所有符合Spring Boot加载条件的的类名,然后把这些类加载到IoC容器中。

文字总结一下,这个大致的流程

  1. 先在AutoConfigurationImportSelector判断自动装配开关是否打开(spring.boot.enableautoconfiguration=true
  2. 然后去获取用于EnableAutoConfiguration注解中的 exclude 和 excludeName。这个exclude都是在AnnoctionAttribuite的两个key
  3. 然后再去加载META-INF/spring.factories,XXXAutoConfiguration的作用就是按需加载组件。(在idea的项目文件树中,有一个目录叫做External Libraries,打开里面的目录可以看到会有一个spring.factories的文件的,里面会有一些配置的信息)
  4. 在这些文件里面会有很多个配置文件,他们并不会全部一次加载,加载的时候会有一个筛选的方法,这个注解叫@ConditionalOnClass(以后再看看这个东西怎么个回事,懒惰了不看了)

以前有个面试官问过我,如何实现一个starter?顺手也总结一下

  1. 首先要创建一个工程,取个名字 test-spring-boot-starter
  2. 然后这个工程要是一个maven的工程,或者说是gradle也行,引入关于Spring Boot的相关依赖

pom文件的伪代码

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>${挑选适合你的版本}</version></dependency>
</dependencies>
  1. 然后这个时候,创建一个xxxxAutoConfiguration
  2. 紧接着需要再这个工程下面,创建一个上面提了很多次的spring.factories,需要有这个玩意才能扫到你。(哦还需要一个META-INF做目录)
  3. 然后就可以测试一下了,随便创建一个新的工程,然后在你的pom文件里加入一个引入一个starter
<dependencies><dependency><groupId>org.mtc.test</groupId><artifactId>test-spring-boot-starter</artifactId><version>${你maven创建的时候自己设置的版本}</version></dependency>
</dependencies>

这就ok了

再一个大的总结

主要的核心就是扫描配置就是基于Spring factories,这个四舍五入等于事先约定好的配置文件,也就是Spring Boot所说的约定大于配置,不需要在通过xml进行配置。

@EnableAutoConfiguration 开启自动装配

自动配置类根据@Conditional来进行筛选按需加载

然后通过引入(eg. pom)的形式来使用

done


http://www.ppmy.cn/embedded/104406.html

相关文章

springboot学习11 (菜品缓存redis)

缓存逻辑分析 目的&#xff1a;减轻数据库压力每个分类下的菜品保存一份缓存数据数据库中菜品数据有变更时清理缓存数据 keyvaluedish_1string(...)dish_2string(...)dish_3string(...) GetMapping("/list")ApiOperation("根据分类id查询菜品")public Res…

JVM 内存参数

文章目录 引言I JVM 内存参数常用参数非Heap堆内存Heap堆内存JIT编译参数GC信息打印GC参数II 例子查看JVM参数III JVM基础知识Java 语言是解释型的OpenJDK和Sun/Oracle JDK和hotspot的关系JDK、JRE、JVM 之间的关系JVM基础功能JVM组成JIT:Just In Time CompilerJVM内存区域JVM…

【awk 】如何将一个文件按照同名字段进行合并?

目录 题目解答 题目 使用awk文本处理工具将一个名为c的文件按照同名字段进行合并&#xff0c;c的内容如下所示&#xff1a; 192.168.1.1: httpd 192.168.1.1: tomcat 192.168.1.2: httpd 192.168.1.2: postfix 192.168.1.3: mysqld 192.168.1.4: httpd示例输出&#xff1a; …

【KingbaseES 人大金仓】| Docker 部署 | 详细步骤

文章目录 版本说明准备工作第 1 步:导入 Docker 镜像第 2 步:创建容器相关说明运行容器第 3 步:查看运行状态第 4 步:使用 ksql 访问数据库第 5 步:修改 license第 6 步:修改配置文件【可选】✅ 本文目标:了解 KingbaseES 数据库、了解 KingbaseES 数据库版本、Docker 部…

安卓AppBarLayout与ViewPager2里的fragment里的webview滑动冲突

今天开发遇见一个头痛的问题&#xff0c;就是AppBarLayout和webview会存在一个冲突问题。如图下 问题出现在webview推到顶端的时候&#xff0c;AppBarLayout并不会跟着响应伸缩&#xff0c;解决办法是 在 webview 包 一个 父的 NestedScrollView 就能解决了。 运行效果入下 更改…

万亿低空经济:无人机飞手考证正当时

随着低空经济的不断发展和国家政策的持续推动&#xff0c;无人机行业正迎来前所未有的发展机遇。低空经济作为一种新兴的综合性经济形态&#xff0c;依托低空空域&#xff0c;通过各类有人驾驶和无人驾驶航空器的低空飞行活动&#xff0c;辐射带动相关领域融合发展。这一领域涉…

苹果M4芯片Mac全面曝光 或10月发布

彭博社的马克・古尔曼&#xff08;Mark Gurman&#xff09;发布博文&#xff0c;曝料称苹果内部正在测试 4 款采用 M4 芯片的 Mac 设备&#xff0c;有望今年秋季&#xff08;可能是 10 月&#xff09;发布。 古尔曼表示苹果计划今年升级 MacBook Pro、Mac mini 和 iMac 产品线&…

华为2024 届秋招招聘——硬件技术工程师-电源方向-机试题(四套)(每套四十题)

华为 2024 届秋招——硬件-电源机试题&#xff08;四套&#xff09;&#xff08;每套四十题&#xff09; 岗位——硬件技术工程师 岗位意向——电源 真题题目分享&#xff0c;完整版带答案(有答案和解析&#xff0c;答案非官方&#xff0c;未仔细校正&#xff0c;仅供参考&am…