Spring Boot 之所以能“开箱即用”,其核心就在于 自动配置机制(Auto Configuration)。本文将深入剖析 Spring Boot 自动配置的工作原理,从注解入手,再到底层的源码机制,揭开 Spring Boot 背后的“魔法”。
一、自动配置的初印象
使用 Spring Boot 时,只需加上 @SpringBootApplication
注解,就能启动整个应用,而不需要手动配置 XML 或繁琐的 Java Config。
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
但你有没有想过,是谁帮我们把 Tomcat、DataSource、MVC 等配置都准备好了?
答案就是:Spring Boot 自动配置机制。
二、自动配置的核心注解:@EnableAutoConfiguration
@SpringBootApplication
是一个组合注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
}
其中最关键的就是:
@EnableAutoConfiguration
它的作用就是开启 Spring Boot 自动配置功能。
三、@EnableAutoConfiguration 背后的秘密
3.1 @EnableAutoConfiguration 的核心实现
查看源码我们会发现,它用到了 Spring 的 @Import 注解:
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
也就是说,它将 AutoConfigurationImportSelector
注册为配置类导入器。
3.2 AutoConfigurationImportSelector 的作用
这个类会扫描 META-INF/spring.factories
文件,并加载所有的自动配置类:
private static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
它会读取其中类似如下的内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
...
这些类就是所谓的 自动配置类(AutoConfiguration Class)。
四、自动配置类的本质
以 DataSourceAutoConfiguration
为例:
@Configuration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
...
}
可以看到,它本质上是一个普通的 @Configuration
配置类,但加了一堆 条件注解(Conditional 系列)。
五、@Conditional 系列注解实现条件加载
自动配置类并不是一定会生效,而是根据当前环境判断是否生效:
注解 | 功能说明 |
---|---|
@ConditionalOnClass |
类路径中有某个类时才生效 |
@ConditionalOnMissingBean |
Spring 容器中没有指定 Bean 时才生效 |
@ConditionalOnProperty |
某个配置属性存在或为指定值时生效 |
@ConditionalOnWebApplication |
是 Web 应用时才生效 |
通过这些注解,Spring Boot 实现了高度解耦、按需加载的自动配置机制。
六、spring.factories 的加载机制
这些自动配置类从哪里来?都定义在 jar 包的:
META-INF/spring.factories
这个文件中,EnableAutoConfiguration
会对应很多个自动配置类列表,它们分布在不同的模块中。
Spring Boot 启动时,会统一通过 SpringFactoriesLoader
加载这些类。
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, classLoader);
七、自定义自动配置(进阶)
你也可以自己编写自动配置类:
- 新建配置类
@Configuration
- 加上
@Conditional
条件注解 - 注册到
META-INF/spring.factories
@Configuration
@ConditionalOnProperty(name = "my.feature.enabled", havingValue = "true")
public class MyAutoConfiguration {
@Bean
public MyService myService() {
return new MyService();
}
}
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyAutoConfiguration
这样,当配置开启时(my.feature.enabled=true
),你的自动配置才会生效。
八、@SpringBootApplication 到底做了什么?
总结起来,@SpringBootApplication
做了三件大事:
@SpringBootConfiguration
: 表示这是一个配置类@ComponentScan
: 启动包扫描,自动发现注解的 Bean@EnableAutoConfiguration
: 启动自动配置机制
九、小结:Spring Boot 自动配置的工作流程
graph TD
A[启动类 @SpringBootApplication] --> B[@EnableAutoConfiguration]
B --> C[导入 AutoConfigurationImportSelector]
C --> D[加载 spring.factories]
D --> E[筛选满足条件的自动配置类]
E --> F[按需注册 Bean 到容器中]
这就是 Spring Boot 自动配置的核心原理:通过注解+条件判断+SPI 加载机制,实现了按需配置,极大简化了开发流程。
十、参考资料
- Spring Boot 官方文档
- Spring 源码分析
- 《Spring 实战》第五版