spring boot 条件化依赖注入通过@conditionalonxxx系列注解按环境、配置、类路径等条件控制bean注册,结合自动配置与自定义condition实现灵活、安全的按需加载,并推荐构造函数注入保障依赖明确性。

Spring Boot 中实现条件化依赖注入,核心是让 Bean 的注册和注入行为“按需发生”——不是所有 Bean 都在启动时无差别加载,而是根据环境、配置、类路径或已有组件等具体条件决定是否生效。这既避免了启动失败,也提升了应用的灵活性和可维护性。
用 @ConditionalOnXXX 系列注解控制 Bean 创建
这是最常用、最直观的方式。Spring Boot 提供了一组基于 @Conditional 的派生注解,直接加在 @Bean 方法或 @Configuration 类上即可生效:
-
@ConditionalOnProperty:按配置项开关,比如
datasource.type=postgresql才创建 PostgreSQL 数据源 -
@ConditionalOnClass:仅当类路径存在某个类(如
Jedis.class)时才加载 Redis 相关 Bean - @ConditionalOnMissingBean:只在容器中还没有同类型 Bean 时才注册,常用于提供默认实现
-
@ConditionalOnBean:依赖另一个特定 Bean 已存在,比如只有配置了
DataSource才启用事务管理器 -
@ConditionalOnWebApplication:区分 Web 环境与非 Web 环境,如只在 Web 应用中注册
WebMvcConfigurer
在自动配置类中组合使用条件逻辑
自动配置(auto-configuration)本质上就是条件化注入的集中体现。一个典型的 autoconfigure 模块会:
- 在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 2.7+)中声明配置类 - 配置类本身用 @ConditionalOnClass 和 @ConditionalOnMissingBean 双重保护,确保安全启用
- 配合 @ConfigurationProperties 绑定外部配置,把条件判断从硬编码转向可配置
例如:DataSourceAutoConfiguration 只有在类路径有 DataSource 类且未手动定义数据源 Bean 时才会生效。
自定义条件注解扩展判断能力
当内置条件不够用时,可以实现 org.springframework.context.annotation.Condition 接口,编写自己的判断逻辑:
- 重写
matches(ConditionContext context, AnnotatedTypeMetadata metadata) - 在方法内可访问环境变量、配置属性、BeanFactory、类加载器等上下文信息
- 再用 @Conditional(YourCustomCondition.class) 标注目标 Bean
比如:只在 JVM 参数含 -Denv=prod 且配置文件中 feature.cache.enabled=true 时才启用缓存组件。
结合构造函数注入保证依赖明确性
条件化注入不改变依赖注入方式本身。推荐始终使用构造函数注入来接收已通过条件筛选后的 Bean:
- 确保依赖不可为空、不可变,提升启动阶段的可预测性
- 即使某 Bean 因条件未满足而未注册,Spring 启动也会直接报错(而非运行时 NPE),问题暴露更早
- 配合 Lombok 的
@RequiredArgsConstructor可减少样板代码
字段注入(@Autowired 在属性上)不推荐,因为它隐藏了条件依赖关系,也难以在单元测试中模拟缺失场景。











