Spring Boot 的自动配置原理,@EnableAutoConfiguration 注解是如何生效的?如何自定义一个 Spring Boot Starter?

一、Spring Boot 自动配置原理

Spring Boot 自动配置的核心是通过约定优于配置的思想,简化 Spring 应用的初始化过程。其核心原理可概括为:基于类路径下的依赖、注解和配置文件,自动生成并注册所需的 Bean 到 Spring 容器中

关键实现机制
  1. @EnableAutoConfiguration 注解这是自动配置的入口注解,通过触发 Spring 的 ImportSelector 机制,扫描并加载类路径下的自动配置类。

  2. SpringFactoriesLoader 加载机制Spring Boot 在启动时会通过 SpringFactoriesLoader 读取 META-INF/spring.factories 文件(该文件包含自动配置类的全限定名),并将这些类加载到 Spring 容器中。

  3. 条件注解过滤自动配置类通过一系列 @Conditional 派生注解(如 @ConditionalOnClass@ConditionalOnMissingBean 等)判断是否满足配置条件,只有条件匹配时才会注册对应的 Bean。

  4. 配置属性绑定通过 @ConfigurationProperties 将 application.properties 或 application.yml 中的配置与自动配置类的属性绑定,实现配置自定义。

二、@EnableAutoConfiguration 注解的生效过程

  1. 注解定义与依赖@EnableAutoConfiguration 注解内部通过 @Import(AutoConfigurationImportSelector.class) 导入了 AutoConfigurationImportSelector 类,该类是自动配置的核心处理器。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class) // 关键:导入选择器
    public @interface EnableAutoConfiguration {
        // ...
    }
    
  2. AutoConfigurationImportSelector 的作用

    • 实现 DeferredImportSelector 接口,在 Spring 容器初始化过程中延迟导入配置类。
    • 核心方法 selectImports() 通过 SpringFactoriesLoader 加载 META-INF/spring.factories 中注册的自动配置类(key 为 EnableAutoConfiguration 的全类名)。
  3. 过滤与排序自动配置类

    • 过滤:通过 @Conditional 注解判断是否满足条件(如类路径是否存在某个类、是否已存在自定义 Bean 等)。
    • 排序:通过 @AutoConfigureBefore@AutoConfigureAfter 等注解保证配置类的加载顺序。
  4. 注册 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. 打包与使用
  1. 打包 Starter通过 Maven 或 Gradle 打包为 Jar 包,安装到本地仓库或发布到远程仓库。

  2. 引入 Starter 依赖在其他 Spring Boot 项目的 pom.xml 中引入:

    <dependency>
        <groupId>com.example</groupId>
        <artifactId>my-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    </dependency>
    
  3. 使用自动配置的 Bean

    @RestController
    public class DemoController {
        @Autowired
        private MyService myService;
    
        @GetMapping("/wrap")
        public String wrap(@RequestParam String content) {
            return myService.wrap(content); // 使用自动配置的 MyService
        }
    }
    
  4. 自定义配置(可选)在 application.properties 中修改配置:

    my.starter.prefix=【
    my.starter.suffix=】
    
4. 关键注解说明
  • @ConfigurationProperties:绑定配置文件中的属性。
  • @ConditionalOnClass:当类路径存在指定类时生效。
  • @ConditionalOnMissingBean:当容器中不存在指定 Bean 时才注册当前 Bean(允许用户自定义 Bean 覆盖默认实现)。
  • @EnableConfigurationProperties:启用配置属性类,使其可被注入到自动配置类中。

通过以上步骤,即可实现一个自定义的 Spring Boot Starter,其核心思想是通过自动配置类和条件注解,在满足特定条件时自动注册 Bean,并允许通过配置文件自定义行为

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值