SpringBoot_02_自动配置原理

【Spring Boot】自动配置原理:@EnableAutoConfiguration 与 Starter 机制

🔑 关键词:Java、Spring Boot、自动配置、@EnableAutoConfiguration、@Conditional、Starter、SPI


一、什么是自动配置?

Spring Boot 自动配置是指:根据你引入的依赖,自动帮你配置好对应的 Bean,不需要手动写 XML 或 @Bean。

📌 一句话理解 :你在 pom.xml 引入了 spring-boot-starter-web,Spring Boot 就自动帮你配好 DispatcherServlet、视图解析器、JSON 转换器等,开箱即用。


二、自动配置的核心流程

复制代码
@SpringBootApplication
        ↓
@EnableAutoConfiguration
        ↓
@Import(AutoConfigurationImportSelector.class)
        ↓
读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        ↓
加载所有自动配置类(xxxAutoConfiguration)
        ↓
根据 @Conditional 条件判断是否生效
        ↓
注册对应的 Bean 到 Spring 容器

三、关键注解详解

3.1 @EnableAutoConfiguration

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration { }

核心是通过 @Import 导入 AutoConfigurationImportSelector,它负责加载所有自动配置类。

3.2 AutoConfigurationImportSelector

java 复制代码
// 简化版逻辑
public class AutoConfigurationImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        // 读取 META-INF/spring/...AutoConfiguration.imports 文件
        // 返回所有自动配置类的全限定类名
        return getCandidateConfigurations(annotationMetadata);
    }
}

配置文件位置:

  • Spring Boot 3.x:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • Spring Boot 2.x:META-INF/spring.factories

3.3 @Conditional 系列注解

@Conditional 是自动配置生效的关键------只有满足条件时,配置类才会生效。

注解 条件
@ConditionalOnClass classpath 中存在某个类时生效
@ConditionalOnMissingClass classpath 中不存在某个类时生效
@ConditionalOnBean 容器中存在某个 Bean 时生效
@ConditionalOnMissingBean 容器中不存在某个 Bean 时生效
@ConditionalOnProperty 配置属性满足某个值时生效
@ConditionalOnWebApplication 当前是 Web 应用时生效

四、源码解读:Web 自动配置

4.1 ServletWebServerFactoryAutoConfiguration

java 复制代码
@AutoConfiguration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
public class ServletWebServerFactoryAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public ServletWebServerFactory webServerFactory(
            @Value("${server.port:8080}") int port) {
        // 创建内嵌 Tomcat
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.setPort(port);
        return factory;
    }

    @Bean
    @ConditionalOnMissingBean
    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();
    }
}

解读:

  • @ConditionalOnWebApplication(type = SERVLET):只有 Servlet 类型 Web 应用才生效
  • @ConditionalOnClass(DispatcherServlet.class):classpath 有 DispatcherServlet 才生效
  • @ConditionalOnMissingBean:如果用户没有自定义,才使用默认配置

这就是"约定优于配置"的实现:

  • 有 web 依赖 → 自动配 Tomcat + DispatcherServlet
  • 你自定义了 → 用你的,不用默认的

4.2 DataSourceAutoConfiguration(数据源自动配置)

java 复制代码
@AutoConfiguration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty("spring.datasource.url")
    public DataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().build();
    }
}

解读:

  • @ConditionalOnClass(DataSource.class):引入了数据库驱动才生效
  • @ConditionalOnProperty("spring.datasource.url"):配置了 URL 才生效
  • @ConditionalOnMissingBean:用户没自定义 DataSource 才创建默认的

五、Starter 机制

5.1 什么是 Starter?

Starter 是一组依赖集合,引入一个 Starter 就等于引入了一组相关依赖,且版本经过验证不会冲突。

xml 复制代码
<!-- 引入这个 Starter,自动包含: -->
<!-- spring-web, spring-webmvc, jackson, tomcat, ... -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

5.2 常用 Starter

Starter 功能
spring-boot-starter-web Web 开发(MVC + Tomcat + Jackson)
spring-boot-starter-data-jpa JPA 数据访问
spring-boot-starter-data-redis Redis 操作
spring-boot-starter-security 安全认证
spring-boot-starter-test 测试(JUnit + Mockito)
spring-boot-starter-actuator 监控和管理
mybatis-spring-boot-starter MyBatis 整合

5.3 Starter 的组成

一个 Starter 通常包含:

  • pom.xml:聚合依赖
  • 自动配置类(xxxAutoConfiguration)
  • 配置属性类(xxxProperties)
  • AutoConfiguration.imports 或 spring.factories:注册自动配置类

六、自定义 Starter

三步走:

① 配置属性类:

java 复制代码
@ConfigurationProperties(prefix = "my.log")
public class LogProperties {
    private boolean enabled = true;
    private String prefix = "[LOG]";
    // getter/setter
}

② 自动配置类:

java 复制代码
@AutoConfiguration
@ConditionalOnWebApplication
@EnableConfigurationProperties(LogProperties.class)
public class LogAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public LogInterceptor logInterceptor(LogProperties props) {
        return new LogInterceptor(props);
    }

    @Bean
    public WebMvcConfigurer logWebMvcConfigurer(LogInterceptor interceptor) {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(interceptor).addPathPatterns("/**");
            }
        };
    }
}

③ 注册 :在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中写入 com.example.LogAutoConfiguration。

其他项目引入该 Starter 依赖后,配置 my.log.enabled=true 即可自动生效。


七、如何查看哪些自动配置生效了?

7.1 启动日志

启动时设置 debug=true:

yaml 复制代码
debug: true

或命令行:java -jar app.jar --debug

控制台会输出 CONDITIONS EVALUATION REPORT:

  • Positive matches:生效的自动配置
  • Negative matches:未生效的自动配置及原因

7.2 IDEA 查看

安装 Spring Boot Assistant 插件,可以在 yml 中直接看到配置对应的自动配置类。


八、面试高频问题

Q1:Spring Boot 自动配置的原理?

答 :@SpringBootApplication 包含 @EnableAutoConfiguration,它通过 @Import(AutoConfigurationImportSelector.class) 加载 AutoConfiguration.imports 中的所有自动配置类。每个配置类上都有 @Conditional 系列注解,只有满足条件(如 classpath 存在某个类、容器中存在某个 Bean、配置属性满足某个值)时,配置类才会生效并注册对应的 Bean。

Q2:@ConditionalOnBean 和 @ConditionalOnMissingBean 的区别?

答 :@ConditionalOnBean 表示容器中存在 某个 Bean 时才生效;@ConditionalOnMissingBean 表示容器中不存在某个 Bean 时才生效。后者常用于提供默认配置------如果用户没有自定义,就使用框架提供的默认 Bean。

Q3:如何自定义 Starter?

答 :三步:① 创建 xxxProperties 配置属性类,用 @ConfigurationProperties 绑定配置项;② 创建 xxxAutoConfiguration 自动配置类,用 @Conditional 控制生效条件;③ 在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中注册配置类的全限定名。


九、总结

知识点 核心要点
自动配置原理 @EnableAutoConfiguration → 加载 imports → @Conditional 条件判断
@Conditional 控制配置类是否生效的核心注解
Starter 一组依赖集合 + 自动配置,开箱即用
自定义 Starter Properties + AutoConfiguration + imports 文件

📝 下一篇预告:《Spring Boot Web 开发》,详解 RESTful API、全局异常处理、拦截器在 Spring Boot 中的实现。

相关推荐
FYKJ_20101 小时前
SSM校园失物招领系统41452-计算机课程设计、毕业设计
java·vue.js·spring boot·python·mysql·typescript·spark
kv1101 小时前
Android studio国内开发有关
java·数据库·android studio
卓怡学长2 小时前
w198基于springboot始于足下健康打卡平台的设计与实现
java·spring boot·spring·intellij-idea
阿狗童鞋2 小时前
Java并发编程实战指南
java·开发语言
子兮曰2 小时前
Node.js 50个优势场景盘点:一个人单干,为啥我多数时候只用它
前端·后端
IT_陈寒2 小时前
我花3小时debug,就因为JavaScript这个隐式转换坑
前端·人工智能·后端
Joe_Wang52 小时前
【从0到1学习JVM · 15】对象在堆里来回倒腾,究竟怎样才会进老年代?
java·jvm·学习·垃圾回收
程序猿阿越2 小时前
containerd如何拉取镜像
后端·kubernetes·源码阅读
一条小小yu2 小时前
为什么使用springboot
java·spring boot·后端