知识模块
☕ Java 知识模块
八、Spring 全家桶
Spring Boot 自动配置

Spring Boot 自动配置

自动配置原理

@SpringBootApplication

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
 
// 等价于
@SpringBootConfiguration      // 配置类
@EnableAutoConfiguration      // 开启自动配置
@ComponentScan                 // 组件扫描
public class Application { }

@EnableAutoConfiguration

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    // 通过 @Import 导入自动配置选择器
}

自动配置流程

1. 启动 SpringApplication

2. 加载 META-INF/spring.factories

3. 读取 EnableAutoConfiguration 配置

4. 根据条件过滤(@Conditional)

5. 注册符合条件的配置类

6. 创建对应的 Bean

条件注解

@Conditional 系列

注解条件
@ConditionalOnClass类路径存在指定类
@ConditionalOnMissingClass类路径不存在指定类
@ConditionalOnBean容器中存在指定 Bean
@ConditionalOnMissingBean容器中不存在指定 Bean
@ConditionalOnProperty配置属性满足条件
@ConditionalOnWebApplication是 Web 应用
@ConditionalOnExpressionSpEL 表达式为 true

示例

@Configuration
@ConditionalOnClass(DataSource.class)  // 类路径有 DataSource
public class DataSourceAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean  // 没有其他 DataSource Bean
    public DataSource dataSource() {
        return new HikariDataSource();
    }
    
    @Bean
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "hikari")
    public HikariDataSource hikariDataSource() {
        return new HikariDataSource();
    }
}

spring.factories

文件位置

META-INF/spring.factories

文件内容

# 自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.config.DataSourceAutoConfiguration,\
com.example.config.WebMvcAutoConfiguration,\
com.example.config.RedisAutoConfiguration
 
# 监听器
org.springframework.context.ApplicationListener=\
com.example.listener.MyListener
 
# 初始化器
org.springframework.context.ApplicationContextInitializer=\
com.example.initializer.MyInitializer

自定义 Starter

1. 创建自动配置类

@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public MyService myService(MyProperties properties) {
        return new MyService(properties.getPrefix());
    }
}

2. 创建配置属性类

@ConfigurationProperties(prefix = "my.service")
public class MyProperties {
    
    private String prefix = "default";
    private boolean enabled = true;
    
    // getter/setter
}

3. 创建 spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration

4. 使用 Starter

<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-spring-boot-starter</artifactId>
</dependency>
my:
  service:
    prefix: "custom"
    enabled: true

常见自动配置

数据源自动配置

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public DataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().build();
    }
}

Redis 自动配置

@Configuration
@ConditionalOnClass(RedisClient.class)
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisClient redisClient(RedisProperties properties) {
        return RedisClient.create(properties.getUrl());
    }
}

配置加载顺序

1. 命令行参数

2. Java 系统属性

3. 操作系统环境变量

4. application-{profile}.properties

5. application.properties

6. @Configuration 类中的 @PropertySource

7. 默认值

排除自动配置

方式一:@SpringBootApplication

@SpringBootApplication(exclude = { 
    DataSourceAutoConfiguration.class,
    RedisAutoConfiguration.class 
})
public class Application { }

方式二:配置文件

spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
      - org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

面试高频问题

Q1: Spring Boot 自动配置原理?

  1. @SpringBootApplication 包含 @EnableAutoConfiguration
  2. @EnableAutoConfiguration 通过 @Import 导入 AutoConfigurationImportSelector
  3. AutoConfigurationImportSelector 读取 META-INF/spring.factories
  4. 根据 @Conditional 条件过滤配置类
  5. 注册符合条件的 Bean

Q2: 如何自定义 Starter?

  1. 创建自动配置类(@Configuration + @Conditional
  2. 创建配置属性类(@ConfigurationProperties
  3. 创建 META-INF/spring.factories
  4. 打包发布

Q3: @Conditional 有哪些常用注解?

注解作用
@ConditionalOnClass类存在时生效
@ConditionalOnMissingBeanBean 不存在时生效
@ConditionalOnProperty配置满足时生效

Q4: 如何排除某个自动配置?

// 方式一
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
 
// 方式二
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

总结

Spring Boot 自动配置核心:
1. @SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan
2. 自动配置类在 META-INF/spring.factories 中注册
3. @Conditional 系列注解控制条件
4. 可通过 exclude 排除自动配置
5. 可自定义 Starter 扩展功能