看看SpringBoot的自动装配原理

2024-09-02 03:28

本文主要是介绍看看SpringBoot的自动装配原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

@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

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:实现自动装配的核心注解

@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

// 继承体系
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

这篇关于看看SpringBoot的自动装配原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1128862

相关文章

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

Springboot处理跨域的实现方式(附Demo)

《Springboot处理跨域的实现方式(附Demo)》:本文主要介绍Springboot处理跨域的实现方式(附Demo),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录Springboot处理跨域的方式1. 基本知识2. @CrossOrigin3. 全局跨域设置4.

springboot security使用jwt认证方式

《springbootsecurity使用jwt认证方式》:本文主要介绍springbootsecurity使用jwt认证方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录前言代码示例依赖定义mapper定义用户信息的实体beansecurity相关的类提供登录接口测试提供一

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

基于SpringBoot实现文件秒传功能

《基于SpringBoot实现文件秒传功能》在开发Web应用时,文件上传是一个常见需求,然而,当用户需要上传大文件或相同文件多次时,会造成带宽浪费和服务器存储冗余,此时可以使用文件秒传技术通过识别重复... 目录前言文件秒传原理代码实现1. 创建项目基础结构2. 创建上传存储代码3. 创建Result类4.

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

Tomcat版本与Java版本的关系及说明

《Tomcat版本与Java版本的关系及说明》:本文主要介绍Tomcat版本与Java版本的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat版本与Java版本的关系Tomcat历史版本对应的Java版本Tomcat支持哪些版本的pythonJ

springboot security验证码的登录实例

《springbootsecurity验证码的登录实例》:本文主要介绍springbootsecurity验证码的登录实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录前言代码示例引入依赖定义验证码生成器定义获取验证码及认证接口测试获取验证码登录总结前言在spring

SpringBoot日志配置SLF4J和Logback的方法实现

《SpringBoot日志配置SLF4J和Logback的方法实现》日志记录是不可或缺的一部分,本文主要介绍了SpringBoot日志配置SLF4J和Logback的方法实现,文中通过示例代码介绍的非... 目录一、前言二、案例一:初识日志三、案例二:使用Lombok输出日志四、案例三:配置Logback一

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s