Spring Boot自动配置原理揭秘

编程入门 行业动态 更新时间:2024-10-22 08:39:11

Spring Boot自动配置<a href=https://www.elefans.com/category/jswz/34/1770123.html style=原理揭秘"/>

Spring Boot自动配置原理揭秘

自动配置原理

  • 概述
    • 原理
      • Spring Boot Starter
      • spring.factories 文件
      • @ConditionalOnX 注解
      • 配置 Bean
      • 配置属性
    • 源码剖析

主页传送门:📀 传送

概述


  Spring Boot 是一个用于创建独立的、生产级别的 Spring 应用程序的框架。它极大地简化了 Spring 应用程序的开发过程,其中一个关键的功能就是自动配置(Auto-Configuration)。

  自动配置可以根据项目需求自动配置各种服务和组件,它可以帮助开发者在不需要显式配置的情况下,快速地构建一个运行的应用程序。

  自动配置是 Spring Boot 的一个核心特性,它通过分析项目的依赖和环境,自动地为应用程序配置 Spring 配置文件。这意味着开发者无需手动配置大量的 Spring Bean,Spring Boot 会根据环境和项目的依赖来智能地为应用程序创建所需的 Bean。

原理


  Spring Boot的自动配置原理基于Java的反射机制和Spring的IoC容器。它通过读取项目中的配置文件(如application.properties或application.yml),根据配置信息自动创建和配置各种服务。

可以概括为以下几个步骤:

Spring Boot Starter


  Spring Boot 项目通常依赖于所谓的 “Starters”,这是一组预定义了常用库的依赖集合。Starters 包含了应用程序所需的所有依赖,比如 Web Starter 会包含用于构建 Web 应用程序的所有必要库。

spring.factories 文件


  在每个 Starter 的 META-INF/spring.factories 文件中,定义了一系列的自动配置类。这些自动配置类会在应用程序启动时被 Spring Boot 自动扫描和加载。

@ConditionalOnX 注解


  在自动配置类中,通常会使用 @ConditionalOnX 注解来控制该自动配置是否生效。这个注解会根据特定的条件(比如类是否在类路径中、特定的 Bean 是否存在等)来决定是否应用这个配置。

配置 Bean


  自动配置类会定义一些必要的 Bean,并使用 @Configuration 注解将它们标记为配置类。这些 Bean 会在 Spring 上下文中被自动注册。

配置属性


  自动配置类还可以通过读取 application.propertiesapplication.yml 文件中的属性来自定义它们的行为。这样,开发者可以根据需要进行定制。

源码剖析


Spring Boot 应用的启动类一般均位于src/main/java根路径下

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

  @SpringBootApplication开启组件扫描和自动配置,而SpringApplication.run则负责启动引导应用程序。@SpringBootApplication是一个复合Annotation,它将三个有用的注解组合在一起:

@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) })
public @interface SpringBootApplication {// ...省略内容
}

  @SpringBootConfiguration就相当于@Configuration,它是 Spring 框架的注解,标明该类是一个JavaConfig配置类。而@ComponentScan启用组件扫描。

  @EnableAutoConfiguration注解表示开启 Spring Boot 自动配置功能,Spring Boot 会根据应用的依赖、自定义的 bean、classpath 下有没有某个类 等等因素来猜测你需要的 bean,然后注册到 IOC 容器中。@EnableAutoConfiguration是如何推算出需求的?首先来看下它的定义:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {// ...省略内容
}

  重点关注点在@Import({AutoConfigurationImportSelector.class}) @Import注解用于导入类,并将这个类作为一个 bean 的定义注册到容器中,这里它将把EnableAutoConfigurationImportSelector作为 bean 注入到容器中,而这个类会将所有符合条件的@Configuration 配置都加载到容器中,查看EnableAutoConfigurationImportSelector代码可以看到:

AutoConfigurationImportSelector 实现了DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered 这些接口。核心代码为

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {//...public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}
}

再来具体看getAutoConfigurationEntry 方法具体是如何判断哪些是需要导入的。

protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return EMPTY_ENTRY;} else {AnnotationAttributes attributes = this.getAttributes(annotationMetadata);List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);configurations = this.removeDuplicates(configurations);Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);this.checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = this.getConfigurationClassFilter().filter(configurations);this.fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);}}

annotationMetadata 参数是一个元数据接口,它提供了对注解元数据的访问权限,通常用于在运行时检查类上的注解。

getAutoConfigurationEntry(annotationMetadata)方法会根据传入的 annotationMetadata返回一个 AutoConfigurationEntry 对象。

AutoConfigurationEntry 是一个内部类,用于封装自动配置项的信息,包括该自动配置项的类名、条件(Conditions)等信息。

  通过获取到的 autoConfigurationEntry 对象,Spring Boot 就能够知道哪些自动配置类需要被导入,从而将它们注册到 Spring 上下文中。

  如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏  🙌一起讨论你的支持就是我✍️创作的动力!					  💞💞💞

更多推荐

Spring Boot自动配置原理揭秘

本文发布于:2023-12-04 20:23:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1662116.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:原理   Spring   Boot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!