在使用 Spring Boot 开发项目时,你可能会惊讶地发现:只引入几个依赖、写一个启动类,项目就能直接跑起来。甚至数据库、Redis、Web MVC 这些组件都能自动配置好,一切似乎“理所当然”。
但你有没有想过:Spring Boot 到底是怎么做到“自动配置”的?你没配的它帮你配了,你配了的它就乖乖让路?
这篇文章,我们就来彻底搞清楚 Spring Boot 自动配置背后的底层机制、关键注解、执行流程,并告诉你如何自定义自己的自动配置类。
一、什么是 Spring Boot 自动配置?
Spring Boot 的一大核心特性就是自动配置(AutoConfiguration)。它的目标是:
根据你引入的依赖和当前的运行环境,自动创建合适的 Bean 对象并注入 Spring 容器中。
比如你引入了 spring-boot-starter-web,它就自动给你配好 DispatcherServlet
、Tomcat
、WebMvcConfigurer
、JSON 序列化等一整套 Web 环境;你再加个 MySQL 依赖,它就自动帮你配置好 DataSource、JdbcTemplate,甚至还连带着事务都给你弄好了。
二、入口注解:@SpringBootApplication
和 @EnableAutoConfiguration
你一定很熟悉这个启动类:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
而 @SpringBootApplication
是一个组合注解,等价于:
@Configuration
@ComponentScan
@EnableAutoConfiguration
其中,@EnableAutoConfiguration
才是自动配置的真正入口。
它的作用就是开启自动配置功能,让 Spring Boot 去扫描并加载所有符合条件的自动配置类。
三、自动配置类从哪儿来?
Spring Boot 使用了 Java 的 SPI(Service Provider Interface)机制,来加载配置类。具体路径是:
META-INF/spring.factories
你可以在源码中搜索这个文件,例如:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
...
也就是说,@EnableAutoConfiguration
会读取这些配置类,把里面的配置都一股脑地加载进 Spring 容器。
但你可能要问:那岂不是所有配置类都加载?那我不用数据库也配个 DataSource 豈不是浪费?
别急,Spring Boot 最聪明的一点在于——它虽然全都加载了,但不会全部生效!
四、智能的关键:条件装配注解 @ConditionalXXX
自动配置类里大量使用了 @Conditional
系列注解。常见的有:
举个例子:DataSourceAutoConfiguration
这个类只有在满足以下条件时才会自动配置数据源:
@Configuration
@ConditionalOnClass({ DataSource.class })
@ConditionalOnProperty(name = "spring.datasource.url")
public class DataSourceAutoConfiguration {
@Bean
public DataSource dataSource(...) {
// 创建 DataSource 实例
}
}
意思是:只有你的类路径中有 javax.sql.DataSource
且配置了 spring.datasource.url
,我才给你自动注入数据库连接池;否则我啥都不做。
所以说,Spring Boot 自动配置虽然“自动”,但其实每一步都经过精密判断。
五、默认配置能不能覆盖?
当然能。Spring Boot 自动配置的另一个贴心设计是:优先级低于用户自定义配置。
大部分自动配置类都会加上:
@ConditionalOnMissingBean
也就是说:只要你手动定义了一个同类型的 Bean,自动配置就不会生效了。
比如你自己写了个 DataSource
配置类,Spring Boot 就不会再帮你自动配置数据源了。
六、自动配置的加载流程(源码级简要分析)
自动配置类的加载过程大致可以分为以下几步:
Spring Boot 启动时调用
SpringApplication.run()
加载并处理
@EnableAutoConfiguration
使用
SpringFactoriesLoader
读取spring.factories
中的配置类列表利用条件注解(如
@ConditionalOnClass
)判断哪些配置生效最终通过
ImportSelector
把匹配的配置类注册为 Bean
这其中最关键的类是:
AutoConfigurationImportSelector
:筛选所有自动配置类SpringFactoriesLoader
:从spring.factories
中读取配置ConditionEvaluator
:根据条件判断是否生效
七、如何查看哪些配置生效了?
开启 debug 模式
在 application.yml
中添加:
debug: true
控制台会输出哪些配置类生效了,哪些被忽略了。
引入 Spring Boot Actuator
加入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
然后访问接口 /actuator/conditions
,可以看到所有自动配置类的启用/禁用状态。
八、自定义自动配置类
Spring Boot 也允许你写自己的自动配置类并注册到全局。
创建配置类:
@Configuration
@ConditionalOnClass(MyService.class)
public class MyServiceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new MyService();
}
}
在
resources/META-INF/spring.factories
中声明:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyServiceAutoConfiguration
只要你的模块被引用,这个自动配置就会生效。
九、总结
🔚 写在最后
Spring Boot 的自动配置不仅提升了开发效率,也让项目结构更加清晰、干净。但是理解它的原理,能让你写出更加可控、可调优的项目。
如果你正在开发自己的 starter 模块,或者在多模块项目中拆分配置,掌握这一套机制尤为重要。
如果你觉得本文有帮助,欢迎点赞、收藏或转发给更多 Spring Boot 开发者!