news 2026/1/19 14:04:20

@AutoConfigureBefore 与 @AutoConfigureAfter

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
@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注解

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/14 10:45:09

做了好几年测试,觉得自己在浪费时间,怎么办?

在测试领域成功的人&#xff0c;他们也是从最基础的测试做起的&#xff0c;也是在点点点的过程中成长的&#xff0c;抛出这个问题时&#xff0c;自己有没有认真的去想下为什么会有这样的想法——浪费时间? 是不是在你所做的工作中已经没有你可以学习的东西了? 是不是你的工…

作者头像 李华
网站建设 2026/1/16 18:44:52

Informed RRT*实现椭圆启发式采样

我来为您添加Informed RRT*功能&#xff0c;在找到第一条路径后使用椭圆采样来加速收敛。以下是需要新增的函数和修改&#xff1a; 以下代码只含新增的部分 class RRTStar { private:// 在私有成员变量中添加bool pathFound;double bestPathCost;std::shared_ptr<Node> g…

作者头像 李华
网站建设 2026/1/16 2:36:00

27.MPSOC FPGA 驱动PCF8574

上一篇记录了AHT20,本篇记录下PCF8574&#xff0c;原理类似&#xff1a;#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/i2c-dev.h> #include <errno.h> …

作者头像 李华
网站建设 2026/1/14 18:22:20

通信系统仿真:数字调制与解调技术_(28).Simulink通信系统仿真

Simulink通信系统仿真 1. Simulink概述 1.1 Simulink简介 Simulink是MATLAB的一个附加产品&#xff0c;主要用于动态系统建模、仿真和分析。Simulink提供了一个图形用户界面&#xff08;GUI&#xff09;&#xff0c;使用户可以通过拖放操作来构建复杂的系统模型。在通信系统仿真…

作者头像 李华