java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot自动配置原理

SpringBoot自动配置的核心注解原理解析

作者:寒士obj

自动配置在面试和日常使用中都是一个高频话题,了解其原理对于深入掌握Spring Boot至关重要,这篇文章主要介绍了SpringBoot自动配置的核心注解原理的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

SpringBoot作为Spring生态系统中的重要组成部分,其最大的特色就是约定优于配置的设计理念,而自动配置机制正是这一理念的核心体现。通过自动配置,SpringBoot能够根据项目中的依赖和配置,自动装配相应的Bean,极大地简化了传统Spring项目的配置工作。

SpringBoot自动配置概述

SpringBoot自动配置是一套智能化的配置机制,它能够根据classpath中存在的jar包、配置文件中的属性值以及其他条件,自动为应用程序配置相应的Bean。这种机制让开发者无需编写大量的XML配置文件或Java配置类,就能快速搭建一个功能完整的Spring应用。自动配置的核心思想是通过条件注解来判断是否需要创建某个Bean。只有当特定条件满足时,相应的配置类才会生效,Bean才会被创建并加入到Spring容器中。

自动配置的核心注解

@SpringBootApplication注解

SpringBoot应用的入口点通常标注有@SpringBootApplication注解,这个注解是一个复合注解,包含了三个重要的注解:

其中@EnableAutoConfiguration是自动配置的核心注解,它负责启动SpringBoot的自动配置机制。

@EnableAutoConfiguration注解解析

@EnableAutoConfiguration注解的源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
    Class<?>[] exclude() default {};
    String[] excludeName() default {};
}

这个注解通过@Import导入了AutoConfigurationImportSelector类,这个类是自动配置机制的核心实现。

AutoConfigurationImportSelector核心实现

AutoConfigurationImportSelector类实现了ImportSelector接口,Spring容器会调用其selectImports方法来获取需要导入的配置类。

selectImports方法分析

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    }
    AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

这个方法首先检查自动配置是否启用,然后调用getAutoConfigurationEntry方法获取自动配置条目。

getAutoConfigurationEntry方法详解

源码如下:

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

这个方法的执行流程包括以下几个步骤:

  1. 获取候选配置类列表
  2. 移除重复的配置类
  3. 获取排除的配置类
  4. 检查排除的配置类是否合法
  5. 从候选配置中移除排除的配置
  6. 通过过滤器进一步筛选配置类
  7. 触发自动配置导入事件


    其实主要的就是getCandidateConfigurationsfilter方法,一个是来得到配置类的List集合,另一个是用来对过滤不符合条件注解的那些配置类。

getCandidateConfigurations方法

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
            getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
            + "are using a custom packaging, make sure that file is correct.");
    return configurations;
}

这个方法通过SpringFactoriesLoader.loadFactoryNames方法从META-INF/spring.factories文件中加载所有的自动配置类。

SpringFactoriesLoader机制

SpringFactoriesLoader是SpringBoot中一个重要的工具类,它负责从classpath下的META-INF/spring.factories文件中加载配置信息。

loadFactoryNames方法实现

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
    ClassLoader classLoaderToUse = classLoader;
    if (classLoaderToUse == null) {
        classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
    }
    String factoryTypeName = factoryType.getName();
    return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}

loadSpringFactories方法核心逻辑

通过SpringFactoriesLoader来加载META-INF/spring.factories文件中的所有自动配置类,并将其缓存起来。

spring.factories文件格式

spring.factories文件采用Properties格式,其中key是接口或抽象类的全限定名,value是实现类的全限定名列表。以spring-boot-autoconfigure包中的spring.factories为例:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
...

条件注解机制

SpringBoot自动配置的智能之处在于条件注解的使用。这些注解决定了配置类在什么条件下才会生效。

自动配置的执行流程

SpringBoot自动配置的完整执行流程可以概括为以下几个阶段:

  1. 首先是启动阶段。当Spring容器启动时,会处理@SpringBootApplication注解,进而处理@EnableAutoConfiguration注解。
  2. 然后是加载阶段。AutoConfigurationImportSelector被调用,从META-INF/spring.factories文件中加载所有候选的自动配置类。
  3. 接下来是过滤阶段。通过各种条件注解对候选的配置类进行过滤,只保留满足条件的配置类。
  4. 最后是实例化阶段。Spring容器实例化通过过滤的配置类,并创建相应的Bean。

总结

SpringBoot的自动配置机制通过条件注解、SpringFactoriesLoader、META-INF/spring.factories文件等技术,实现了智能化的Bean配置。它大大简化了Spring应用的配置工作,理解自动配置的原理不仅有助于更好地使用SpringBoot,也能帮助我们在必要时创建自己的自动配置,提高开发效率。

到此这篇关于SpringBoot自动配置的核心注解原理的文章就介绍到这了,更多相关SpringBoot自动配置原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文