找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2045

积分

0

好友

291

主题
发表于 5 天前 | 查看: 11| 回复: 0

在 Spring Boot 的开发日常中,我们几乎每天都要和配置类打交道。 很多同学有这样的误区:“配置类不就是加个 @Configuration,再写几个 @Bean 吗?”

如果你只是在写业务项目,这话没毛病。但如果你想进阶架构师,开始尝试封装公共组件编写 Starter,或者维护公司内部的 SDK,你会发现:简单的 @Configuration 根本不够用,甚至会带来严重的加载顺序问题包扫描耦合

今天,我们就从零开始,彻底讲透 Spring Boot 配置体系中的这一对“孪生兄弟”:@Configuration@AutoConfiguration


环境准备:一切的起点

要演示这两个注解的区别,我们首先需要一个标准的 Spring Boot 环境。

在 Maven 依赖中,我们不需要引入复杂的第三方包,核心只依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

注:本文基于 Spring Boot 2.7+ 及 3.x 版本讲解,这是目前官方推荐的规范。


基础篇:@Configuration 的正确姿势

场景: 你正在开发一个业务系统(Application),比如一个电商平台的订单服务。你需要配置一个数据库连接池,或者注册一个业务 Bean。

用法: 这是我们最熟悉的方式。

  1. 创建一个类。
  2. 打上 @Configuration 注解。
  3. Spring 启动时,通过 @ComponentScan(通常包含在启动类里)扫描当前包及其子包,发现这个类,并加载其中的 Bean。

代码示例
Spring @Configuration示例代码

点评

@Configuration 是 Spring 框架的原住民。 它的特点是:依赖包扫描。也就是说,这个配置类必须在你的主启动类(Application)的扫描范围内。适用范围: 业务逻辑、应用内部配置。


进阶篇:@AutoConfiguration 的登场

场景: 你的身份变了。你现在要为全公司的 50 个微服务项目封装一个“通用日志组件”。 这个组件作为一个独立的 .jar 包发布。

问题来了:别的项目引入你的 jar 包后,他们的启动类包名是 com.a,而你的组件包名是 com.b包名不一致,Spring 根本扫不到你的 @Configuration。 强迫别人在启动类上加 @ComponentScan("com.b")?太 Low 了,且高耦合。

多模块项目结构与配置类代码
项目运行结果展示未被扫描的配置类

解法: 使用 @AutoConfiguration 配合 SPI 机制

步骤一:修改注解
不再使用 @Configuration,而是使用 Spring Boot 2.7 引入的专用注解:

// 这是一个给别人用的自动配置类
@AutoConfiguration
public class MyLibraryAutoConfig {
    @Bean
    @ConditionalOnMissingBean // 优雅的退让,允许用户覆盖
    public MyService myService() {
        return new MyService();
    }
}

步骤二:注册 SPI 文件 (关键)
我们不靠扫描,靠“登记”。 在 src/main/resources 下创建目录 META-INF/spring/,并新建文件 org.springframework.boot.autoconfigure.AutoConfiguration.imports

文件内容

com.yann.library.MyLibraryAutoConfig

点评

只要完成了这两步,无论谁引用你的 jar 包,Spring Boot 都会通过读取 .imports 文件自动把配置加载进来。这才是真正的“开箱即用”


核心篇:为什么要区分这两个?

很多同学会问:“以前用 spring.factories@Configuration 不也能自动装配吗?为什么要搞个新注解?”

这就涉及到了 Spring Boot 的加载生命周期设计哲学。

1. 加载顺序 (Ordering) —— 这是最大的坑

  • @Configuration (应用级):被视为“一等公民”,优先加载。
  • @AutoConfiguration (组件级):被视为“二等公民”,永远在应用级配置之后加载

为什么这么设计?是为了方便覆盖! 想象一下:你写了一个 Starter,里面有一个默认的 Bean。用户觉得不好用,在自己的代码里(@Configuration)重写了一个同名的 Bean。

  • 因为用户的 @Configuration执行,容器里先有了 Bean。
  • 等到你的 @AutoConfiguration执行时,配合 @ConditionalOnMissingBean,发现容器里已经有了,你的默认逻辑就会自动跳过。

2. 语义分离
Spring 官方希望明确界限:

  • @Configuration = 用户配置(App Domain)
  • @AutoConfiguration = 框架/库配置(Infrastructure Domain)

总结与建议

最后,为大家整理了一张决策表,建议保存:

维度 @Configuration @AutoConfiguration
生效机制 依赖包扫描 (@ComponentScan) 依赖 SPI 文件 (.imports)
加载优先级 (先于自动配置) (后于应用配置)
典型用途 业务逻辑、本项目配置 开发 Starter、公共类库
推荐包名 与启动类同包或子包 独立包名,无限制

一句话总结:如果你在写业务代码,请用 @Configuration;如果你在造轮子、写 SDK,请务必拥抱 @AutoConfiguration

希望这篇文章能帮你理清这两个核心配置注解的区别。如果你想了解更多关于系统架构或高级 Java 开发技巧,欢迎在 云栈社区 交流探讨。




上一篇:IceWM 4.0轻量级窗口管理器发布:Alt+Tab体验升级与HiDPI支持
下一篇:慎用TypeScript Enum:运行时陷阱与as const/字面量联合的替代方案
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-10 18:25 , Processed in 0.303938 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表