Springboot自动配置原理

目录

一、引言

二、Spring Boot自动装配揭秘

    1.自动装配的定义

    2.@SpringBootApplication注解

      3.spring.factories 文件

      4.条件装配(@Conditional系列注解)

示例:DataSourceAutoConfiguration

三、自动配置的工作流程

四、Spring Boot自动装配的实际案例

五、Spring Boot自动装配的优势

六、总结


一、引言

在Java开发领域,Spring Boot以其独特的自动装配机制,彻底改变了传统开发模式。过去,开发者常常被Spring项目的复杂配置所困扰,版本冲突和配置错误更是家常便饭。然而,Spring Boot的自动装配功能的出现,使得项目几乎可以实现“零配置”启动,让开发者能够将主要精力集中在业务逻辑的实现上,从而极大地提高了开发效率。接下来,我们将深入剖析Spring Boot自动装配背后的原理。

二、Spring Boot自动装配揭秘

    1.自动装配的定义

Spring Boot的自动装配是一套智能且高效的依赖注入与配置协调系统,遵循“约定优于配置”的原则。在项目启动阶段,它能够自动识别类路径下的各类组件及配置信息,并依据预先设定的精细规则完成装配任务。

    2.@SpringBootApplication注解

自动配置的起点通常是@SpringBootApplication注解,它是一个组合注解,包含了三个重要注解:

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

  • @SpringBootConfiguration:等同于@Configuration,为自动装配的配置环节搭建基础框架。
  • @EnableAutoConfiguration:自动配置的核心,通过@Import(AutoConfigurationImportSelector.class)引入AutoConfigurationImportSelector,实现智能的自动配置。

@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 {};
}

AutoConfigurationImportSelector 类的继承体系如下:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
 
}
 
public interface DeferredImportSelector extends
ImportSelector {
 
}
 
public interface ImportSelector {
    String[]
selectImports(AnnotationMetadata var1);
}

   可以看出,AutoConfigurationImportSelector类实现了ImportSelector接口,也就实现了这个接口中的selectImports方法,该方法主要用于获取所有符合条件的类的全限类名,这些类需要被加载到IOC容器中。 

public String[] selectImports(AnnotationMetadata annotationMetadata) {
        // 1.检查是否启用自动配置
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
        // 2.获取所有需要装配的bean
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
}

getAutoConfigurationEntry方法通过一系列步骤,包括检查自动配置是否启用、获取候选配置、去除重复项、获取排除配置、检查排除的类是否有效、移除排除项、过滤配置,最终生成一个包含自动配置类和排除配置类的AutoConfigurationEntry对象。这个方法是Spring Boot自动配置功能的核心,它确保了只有符合条件的自动配置类被加载到Spring应用上下文中。

/**
 * 获取自动配置入口信息,包括需要加载的自动配置类和需要排除的配置类。
 *
 * @param annotationMetadata 当前注解的元数据,提供了关于注解的信息,用于决定哪些自动配置类应该被导入。
 * @return 包含自动配置类和排除配置类的AutoConfigurationEntry对象。
 */
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    // 1. 如果自动配置没有被启用,则返回一个空的AutoConfigurationEntry对象
    if (!this.isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    } else {
        // 2. 从注解元数据中获取注解属性
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        // 3. 获取所有候选的自动配置类名
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        // 4. 去除候选配置中的重复项
        configurations = this.removeDuplicates(configurations);
        // 获取需要被排除的自动配置类名
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        // 检查排除的类是否在候选配置中,如果不在,则抛出异常
        this.checkExcludedClasses(configurations, exclusions);
        // 从候选配置中移除排除项
        configurations.removeAll(exclusions);
        // 使用ConfigurationClassFilter过滤候选配置
        configurations = this.getConfigurationClassFilter().filter(configurations);
        // 触发自动配置导入事件,通知所有监听器自动配置类即将被导入
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        // 创建并返回一个新的AutoConfigurationEntry对象,包含过滤后的配置和排除配置
        return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
    }
}

  • @ComponentScan:负责搜索项目中的组件,为后续装配工作提供资源支持。

      3.spring.factories 文件

Spring Boot 的自动配置是通过 spring.factories 文件来实现的。spring.factories 文件位于 META-INF 目录下,它是一个标准的 Java 属性文件,用于定义自动配置类。

在 Spring Boot 的 spring-boot-autoconfigure 模块中,META-INF/spring.factories 文件定义了大量的自动配置类。例如:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
...

这些自动配置类会根据项目的依赖和配置,自动配置相应的 Bean。

      4.条件装配(@Conditional系列注解

Spring Boot并非盲目加载所有自动配置类,每个自动配置类通常都会运用@Conditional系列注解来实现有条件的加载。这极大地优化了资源配置,让自动装配更贴合项目实际需求。常见的条件注解有:

  • @ConditionalOnClass:当类路径中存在某个类时才生效。
  • @ConditionalOnMissingBean:当Spring上下文中不存在某个Bean时才生效。
  • @ConditionalOnProperty:当某个配置属性满足特定条件时才生效。
  • @ConditionalOnBean:当Spring上下文中存在某个Bean时才生效。
示例:DataSourceAutoConfiguration

Spring Boot 中DataSourceAutoConfiguration 是配置数据源的自动配置类,它的源码如下:

@Configuration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({DataSourcePoolMetadataProvidersConfiguration.class,
         DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
 
    @Bean
    @ConditionalOnMissingBean
    public DataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().build();
    }
}

@ConditionalOnClass(DataSource.class):只有当类路径下存在 DataSource 类时,才进行数据源的自动配置。
@ConditionalOnMissingBean:如果 Spring 上下文中没有其他 DataSource Bean,则自动配置一个。

 只有当这些条件满足时,DataSourceAutoConfiguration才会被实例化和执行,这意味着Spring Boot在启动过程中,并不会盲目的加载spring.factories中的每一个自动配置类,而是基于运行环境和应用的配置智能选择激活配置。

三、自动配置的工作流程

  1. 收集自动配置类:启动时,AutoConfigurationImportSelector从spring.factories文件中读取所有的自动配置类,并通过@Import导入这些类。
  2. 条件检查:自动配置类的加载不是无条件的,Spring Boot会根据@Conditional注解进行条件检查,确保只有符合条件的自动配置类才会生效。
  3. 注入所需的Bean:一旦自动配置类通过条件检查,Spring Boot就会根据这些配置类注册所需的Bean。
  4. 允许用户覆盖自动配置:自动配置并不是强制的。用户可以通过显式声明自己的Bean来覆盖自动配置的默认行为。

四、Spring Boot自动装配的实际案例

  1. Web应用自动配置:如DispatcherServletAutoConfiguration负责自动配置Spring MVC的核心组件。
  2. 数据库连接池自动配置:如DataSourceAutoConfiguration和DataSourceProperties共同负责自动配置数据源。

五、Spring Boot自动装配的优势

  • 提高开发效率:开发者摆脱繁琐配置工作,聚焦业务功能迭代。
  • 降低学习成本:自动装配机制降低入门难度,使新手无需陷入配置困境。
  • 保证一致性:自动装配由框架统一管理,不同项目结构与配置趋于一致,便于团队协作和代码维护。

六、总结

Spring Boot的自动装配机制为Java开发注入了强大动力。深入理解其原理和流程,不仅有助于开发者更高效地开发项目,还为进一步探索定制化自动装配、拓展框架应用边界提供了可能。随着技术的不断进步,相信Spring Boot的自动装配机制将会在未来发挥更大的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值