当前位置: 首页 > news >正文

@AutoConfigureBefore 与 @AutoConfigureAfter

目录

1、介绍

1.1、设计目的

1.2、定义

1.3、作用域

1.4、设计限制

2、应用

2.1、使用场景

2.2、工作原理

2.3、实战示例

3、常见误区与最佳实践

3.1、最佳实践

3.2、常见误区

3.3、与其他顺序控制注解对比


前沿

控制 Spring Boot 自动配置顺序:

“我的自定义配置为什么没生效?明明加了@ConditionalOnBean,却还是报NoSuchBeanDefinitionException!”

如下所示:

如果你也曾被这类问题困扰,那很可能不是条件注解写错了,而是自动配置的执行顺序出了问题

在 Spring Boot 的自动装配体系中,时机决定一切。而 @AutoConfigureBefore和@AutoConfigureAfter,正是你掌控这一时机的“时间控制器”。

背景:为什么需要控制自动配置顺序?

Spring Boot 的魅力在于“约定优于配置”,其核心是自动配置(Auto-configuration)——通过 spring.factories 或 AutoConfiguration.imports声明一系列 @Configuration 类,在应用启动时按需加载。

但现实世界并非理想模型。多个自动配置类之间往往存在隐式依赖关系

  • 我的 AuditLogAutoConfiguration 需要 DataSource
  • 我的 CustomRedisTemplate 要覆盖默认实现
  • 我的 TraceInterceptor 必须在 Spring MVC 初始化之后注册

如果没有顺序控制,Spring 容器可能在 DataSource 还未创建时就尝试初始化你的 AuditService,导致启动失败。

于是,Spring Boot 提供了 @AutoConfigureBefore@AutoConfigureAfter—— 它们不是“可选项”,而是构建可靠自动配置的必备工具


1、介绍

1.1、设计目的

Spring Boot 的自动配置基于 条件装配(@Conditional),但多个自动配置类之间可能存在隐式依赖,“我的自动配置必须在 DataSourceAutoConfiguration 之后运行,因为我要注入DataSourceBean!”

如果没有顺序控制,Spring 无法保证 DataSource 已经创建,导致启动失败。

为了解决自动配置的“依赖顺序”问题,@AutoConfigureBefore 和 @AutoConfigureAfter 就是为此而生。

1.2、定义

如下所示:

注解作用
@AutoConfigureAfter当前自动配置类应在指定类之后执行
@AutoConfigureBefore当前自动配置类应在指定类之前执行

代码如下所示:

@AutoConfigureAfter({DataSourceAutoConfiguration.class, RedisAutoConfiguration.class}) @AutoConfigureBefore(WebMvcAutoConfiguration.class) public class MyCustomAutoConfiguration { // ... }

1.3、作用域

1.@AutoConfigureAfter:请在我指定的自动配置类之后执行我。

代码如下所示:

@AutoConfigureAfter(DataSourceAutoConfiguration.class) public class MyServiceAutoConfiguration { ... }

效果

确保 MyServiceAutoConfiguration 在 DataSourceAutoConfiguration之后被处理,从而能安全地注入 DataSource Bean。

2.@AutoConfigureBefore:“请在我指定的自动配置类之前执行我。

代码如下所示:

@AutoConfigureBefore(RedisAutoConfiguration.class) public class CustomRedisTemplateConfiguration { ... }

效果

确保你的 RedisTemplate 先于 Spring Boot 默认配置注册,从而通过 @Primary 或@ConditionalOnMissingBean 实现覆盖。

1.4、设计限制

仅作用于自动配置类,这两个注解只影响被 Spring Boot 自动配置机制管理的类,即:

1、在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 3.x)

2、或META-INF/spring.factories(Spring Boot 2.x)中声明的配置类

它们对普通@Configuration类无效!普通 Bean 的依赖应使用 @DependsOn。


2、应用

2.1、使用场景

场景1:依赖其他自动配置创建的 Bean

需求:自定义一个 UserService,它依赖 DataSource。

代码如下所示:

@Configuration @AutoConfigureAfter(DataSourceAutoConfiguration.class) // 必须在 DataSource 之后 public class UserServiceAutoConfiguration { @Bean @ConditionalOnBean(DataSource.class) // 确保 DataSource 存在 public UserService userService(DataSource dataSource) { return new UserService(dataSource); } }

为什么需要@AutoConfigureAfter?UserService

即使有 @ConditionalOnBean,如果 UserServiceAutoConfiguration 先于 DataSourceAutoConfiguration 执行,DataSource 还未注册,条件判断会失败,UserService 不会被创建。

场景2:覆盖或增强已有自动配置

需求:自定义 RedisTemplate,替换 Spring Boot 默认的。

代码如下所示:

@Configuration @AutoConfigureBefore(RedisAutoConfiguration.class) // 在 Redis 自动配置 *之前* 执行 public class CustomRedisTemplateConfiguration { @Bean @Primary // 覆盖默认 public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } }

为什么用@AutoConfigureBefore?

确保你的 @Primary. RedisTemplate 先注册,这样当 RedisAutoConfiguration 尝试创建自己的 RedisTemplate 时,会因 @ConditionalOnMissingBean 条件不满足而跳过。

场景3:Starter 组件间的依赖

需求:你开发了一个 my-starter,它依赖 spring-boot-starter-data-jpa。

在 my-starter 的自动配置类中:

@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class) public class MyStarterAutoConfiguration { // 使用 JpaRepository }

2.2、工作原理

Spring Boot 在启动时执行,如何排序?

如下所示:

3.1、扫描所有自动配置候选类:

从 classpath 下的 AutoConfiguration.imports 文件读取全限定类名。

Spring Boot 在启动时:扫描所有 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

3.2、构建依赖图:

解析每个类上的 @AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder。

3.3、拓扑排序:

使用 Kahn 算法进行有向无环图(DAG)排序,确保依赖顺序。

3.4、按序注册 Bean:

依次处理每个自动配置类,执行其中的 @Bean 方法。

⚠️注意:这些注解只影响自动配置类之间的顺序,不影响普通 @Configuration 类!

2.3、实战示例

目标:创建一个日志追踪 Starter,依赖 Web 自动配置

1. 自动配置类

@Configuration @AutoConfigureAfter(WebMvcAutoConfiguration.class) // 必须在 Web 配置之后 @ConditionalOnWebApplication public class TraceAutoConfiguration { @Bean public TraceInterceptor traceInterceptor() { return new TraceInterceptor(); } @Bean public TraceWebMvcConfigurer traceWebMvcConfigurer(TraceInterceptor interceptor) { return new TraceWebMvcConfigurer(interceptor); } }

2. WebMvcConfigurer 实现

public class TraceWebMvcConfigurer implements WebMvcConfigurer { private final TraceInterceptor interceptor; public TraceWebMvcConfigurer(TraceInterceptor interceptor) { this.interceptor = interceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(interceptor); } }

3. 注册到 spring.factories(Spring Boot 2.x)或 AutoConfiguration.imports(3.x)

# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports com.example.TraceAutoConfiguration

效果

  • 只有在 Web 环境下才生效
  • 确保 WebMvcConfigure 被正确注册到 Spring MVC

场景1:依赖其他自动配置创建的 Bean

需求:创建一个审计服务,依赖数据库。

@Configuration @AutoConfigureAfter(DataSourceAutoConfiguration.class) // 关键! @ConditionalOnClass(JdbcTemplate.class) @ConditionalOnBean(DataSource.class) public class AuditServiceAutoConfiguration { @Bean public AuditService auditService(DataSource dataSource) { return new AuditService(dataSource); } }

为什么必须加@AutoConfigureAfter?避免因顺序问题导致 @ConditionalOnBean 失效。

场景2:覆盖默认自动配置

需求:自定义 RedisTemplate,使用 JSON 序列化。

@Configuration @AutoConfigureBefore(RedisAutoConfiguration.class) // 在默认配置前执行 public class CustomRedisConfig { @Bean @Primary public RedisTemplate<String, Object> redisTemplate( RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } }

效果

Spring Boot 的 RedisAutoConfiguration 会因 @ConditionalOnMissingBean(RedisTemplate.class)而跳过自身创建逻辑。

场景 3:Starter 组件间的协作

需求:开发一个 my-cache-starter,它依赖 spring-boot-starter-data-redis。

// my-cache-starter 的自动配置 @AutoConfigureAfter(RedisAutoConfiguration.class) @ConditionalOnBean(RedisConnectionFactory.class) public class MyCacheAutoConfiguration { @Bean public MyCacheService cacheService(RedisTemplate redisTemplate) { return new MyCacheService(redisTemplate); } }

优势:用户只需引入你的 Starter,无需关心底层 Redis 是否已配置。


3、常见误区与最佳实践

3.1、最佳实践

1. 组合使用多个类

@AutoConfigureAfter({ DataSourceAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class })

2. 配合 @AutoConfigureOrder 做全局排序

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter(LoggingAutoConfiguration.class) public class TracingAutoConfiguration { ... }

3. 优先使用条件注解,而非强依赖顺序

// 更健壮的方式 @ConditionalOnBean(DataSource.class) @AutoConfigureAfter(DataSourceAutoConfiguration.class) // 双重保险

❌ 避免:循环依赖

// A.java @AutoConfigureAfter(B.class) // B.java @AutoConfigureAfter(A.class) // 启动失败!

3.2、常见误区

误区 1:以为能控制任意 Bean 的顺序

@AutoConfigureAfter只控制自动配置类的执行顺序,不能控制普通 Bean 的创建顺序。
普通 Bean 用 @DependsOn 或 @Order。

误区 2:过度使用,导致循环依赖

// A.java @AutoConfigureAfter(B.class) // B.java @AutoConfigureAfter(A.class) // 💥 循环依赖!

最佳实践:

  1. 优先使用@ConditionalOnBean,而非强依赖顺序
  2. 只在必要时使用(如确实需要前置 Bean)
  3. 明确指定具体类,避免模糊依赖
  4. 配合@AutoConfigureOrder做更精细控制(值越小越先执行)

3.3、与其他顺序控制注解对比

如下所示:@AutoConfigureOrder

注解作用范围适用场景
@AutoConfigureBefore/After自动配置类之间Starter 开发、定制 AutoConfig
@Order同类 Bean 排序(如 Interceptor、Filter)定义拦截器执行顺序
@DependsOn任意 Bean 依赖强制 A 在 B 之前初始化
@AutoConfigureOrder自动配置类全局排序设置基础配置(如日志)最先执行

能用条件注解决不用顺序控制;必须用时,优先选@AutoConfigureAfter。


总结

问题答案
什么时候用@AutoConfigureAfter?当你的自动配置依赖其他 AutoConfig 创建的 Bean
什么时候用@AutoConfigureBefore?当你要覆盖或拦截其他 AutoConfig 的行为
能否控制普通配置类❌ 不能,仅限自动配置类
是否必须使用否,但能避免 @ConditionalOnBean 失效

自动配置的顺序:决定了 Spring Boot 应用的“装配逻辑”。而 @AutoConfigureBefore/After,就是你手中的“装配指南针”。

合理使用它们,你的 Starter 将更加健壮、可组合、可预测。


参考文章:

1、SpringBoot之@AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder注解

http://www.cnnetsun.cn/news/70006.html

相关文章:

  • 整体设计 之28 整体设计 架构表表述总表的 完整程序(之27 的Q268 )(codebuddy)
  • 云手机 实体手机的云端延伸
  • 交换机和网卡的 PFC 机制工作原理与实例解析
  • UI自动化测试常见面试题
  • Linux OOM 问题之 DMSERVER 受害者
  • Flutter引擎裁剪与鸿蒙方舟编译协同优化
  • STM32CubeMX的main.c开头介绍
  • 26.MPSOC FPGA linux读AHT20传感器
  • 嵌入式系统时序图完全指南:从原理到实战
  • 小团队与大团队的管理差异
  • [CISCN2019 华东南赛区]Web4
  • AI编程革命!Claude Skills大揭秘:小白也能快速上手的Agent开发神器,大模型开发者必看!
  • 内点法求最优潮流附matlab代码
  • 三相PWM整流器有限集模型预测电流控制附Simulink仿真模型
  • 光伏四可“可观”功能:光伏电站全景数字化的底层支撑技术
  • 如何用FLUX.1-dev镜像在本地部署下一代AI绘画模型?
  • 基于 Comsol 移动网格方法的激光熔池流动数值模拟
  • BLDC无刷直流电机Matlab仿真:转速电流双闭环控制及有感无感换相方式研究
  • [光学原理与应用-491]:水冷机、零气模块CDA、功率计等影响266皮秒紫外激光器的种子源1064nm功率稳定性结果的主要因素有哪些?
  • 昆仑通态MCGS与欧姆龙E5CC温控器通讯实战:PID模式及输出启停控制
  • 通达信〖逆势突破强牛〗指标公式 逆市环境中率先突破前期重要压力位 较强内在上涨动力
  • 基于扰动观测器的永磁同步电机(PMSM)模型预测控制(MPC)仿真探索
  • AEB联合仿真算法设计:Carsim2019.0+Matlab/Simulink2021a实现...
  • Java毕设选题推荐:基于springboot个人博客系统的设计与实现基于SpringBoot+Vue个人博客系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java毕设选题推荐:基于springboot停车场车位预约系统基于Java springboot停车场管理系统停车位预约【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java毕设选题推荐:基于springboot的无人化、线上化、数据化海洋馆预约系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Ascend C高级API应用:InitGlobalMemory与Pad操作的底层原理
  • Java毕设选题推荐:基于Java Web的新能源汽车信息咨询服务基于SpringBoot+Vue的新能源汽车信息咨询服务的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:OPA 集成指南:从原理到实践
  • Object.defineProperty和Proxy实现拦截的区别