一、Spring Boot 自动配置原理
Spring Boot 自动配置的核心是通过约定优于配置的思想,简化 Spring 应用的初始化过程。其核心原理可概括为:基于类路径下的依赖、注解和配置文件,自动生成并注册所需的 Bean 到 Spring 容器中。
关键实现机制
-
@EnableAutoConfiguration 注解这是自动配置的入口注解,通过触发 Spring 的 ImportSelector 机制,扫描并加载类路径下的自动配置类。
-
SpringFactoriesLoader 加载机制Spring Boot 在启动时会通过
SpringFactoriesLoader
读取META-INF/spring.factories
文件(该文件包含自动配置类的全限定名),并将这些类加载到 Spring 容器中。 -
条件注解过滤自动配置类通过一系列
@Conditional
派生注解(如@ConditionalOnClass
、@ConditionalOnMissingBean
等)判断是否满足配置条件,只有条件匹配时才会注册对应的 Bean。 -
配置属性绑定通过
@ConfigurationProperties
将application.properties
或application.yml
中的配置与自动配置类的属性绑定,实现配置自定义。
二、@EnableAutoConfiguration 注解的生效过程
-
注解定义与依赖
@EnableAutoConfiguration
注解内部通过@Import(AutoConfigurationImportSelector.class)
导入了AutoConfigurationImportSelector
类,该类是自动配置的核心处理器。@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) // 关键:导入选择器 public @interface EnableAutoConfiguration { // ... }
-
AutoConfigurationImportSelector 的作用
- 实现
DeferredImportSelector
接口,在 Spring 容器初始化过程中延迟导入配置类。 - 核心方法
selectImports()
通过SpringFactoriesLoader
加载META-INF/spring.factories
中注册的自动配置类(key 为EnableAutoConfiguration
的全类名)。
- 实现
-
过滤与排序自动配置类
- 过滤:通过
@Conditional
注解判断是否满足条件(如类路径是否存在某个类、是否已存在自定义 Bean 等)。 - 排序:通过
@AutoConfigureBefore
、@AutoConfigureAfter
等注解保证配置类的加载顺序。
- 过滤:通过
-
注册 Bean 到容器满足条件的自动配置类会被 Spring 容器解析,其内部定义的
@Bean
方法会生成对应的 Bean 并注册到容器中。
三、自定义 Spring Boot Starter
Starter 是 Spring Boot 的核心组件,本质是一个 Maven 依赖包,通过自动配置简化第三方库的集成。自定义 Starter 需遵循以下步骤:
1. 项目结构
my-spring-boot-starter/
├── src/main/java/
│ └── com/example/starter/
│ ├── autoconfigure/ // 自动配置类
│ │ └── MyAutoConfiguration.java
│ ├── properties/ // 配置属性类
│ │ └── MyProperties.java
│ └── service/ // 业务服务类
│ └── MyService.java
└── src/main/resources/
└── META-INF/
└── spring.factories // 注册自动配置类
2. 核心代码实现
(1)定义配置属性类(绑定 application 配置)
// MyProperties.java
@ConfigurationProperties(prefix = "my.starter") // 绑定配置前缀
public class MyProperties {
private String prefix = "defaultPrefix";
private String suffix = "defaultSuffix";
// getter 和 setter
}
(2)定义业务服务类
// MyService.java
public class MyService {
private final MyProperties properties;
// 构造器注入配置属性
public MyService(MyProperties properties) {
this.properties = properties;
}
public String wrap(String content) {
return properties.getPrefix() + content + properties.getSuffix();
}
}
(3)定义自动配置类
// MyAutoConfiguration.java
@Configuration
@EnableConfigurationProperties(MyProperties.class) // 启用配置属性
@ConditionalOnClass(MyService.class) // 当类路径存在 MyService 时生效
public class MyAutoConfiguration {
private final MyProperties properties;
// 注入配置属性
public MyAutoConfiguration(MyProperties properties) {
this.properties = properties;
}
// 注册 MyService 到容器,当容器中不存在该 Bean 时才注册
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new MyService(properties);
}
}
(4)注册自动配置类(spring.factories)
在 src/main/resources/META-INF/spring.factories
中添加:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.starter.autoconfigure.MyAutoConfiguration
3. 打包与使用
-
打包 Starter通过 Maven 或 Gradle 打包为 Jar 包,安装到本地仓库或发布到远程仓库。
-
引入 Starter 依赖在其他 Spring Boot 项目的
pom.xml
中引入:<dependency> <groupId>com.example</groupId> <artifactId>my-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency>
-
使用自动配置的 Bean
@RestController public class DemoController { @Autowired private MyService myService; @GetMapping("/wrap") public String wrap(@RequestParam String content) { return myService.wrap(content); // 使用自动配置的 MyService } }
-
自定义配置(可选)在
application.properties
中修改配置:my.starter.prefix=【 my.starter.suffix=】
4. 关键注解说明
@ConfigurationProperties
:绑定配置文件中的属性。@ConditionalOnClass
:当类路径存在指定类时生效。@ConditionalOnMissingBean
:当容器中不存在指定 Bean 时才注册当前 Bean(允许用户自定义 Bean 覆盖默认实现)。@EnableConfigurationProperties
:启用配置属性类,使其可被注入到自动配置类中。
通过以上步骤,即可实现一个自定义的 Spring Boot Starter,其核心思想是通过自动配置类和条件注解,在满足特定条件时自动注册 Bean,并允许通过配置文件自定义行为。