Spring条件化装配(@Conditional)

通俗易懂!Spring 条件化装配 @Conditional 全家福(2025 面试+实战必备,背完直接起飞)

一图看懂 Spring 条件装配全体系(面试画图神器)

@Conditional(爷爷,Spring 4.0 出生)
├── @Profile                 → 根据环境(dev/test/prod)切换
├── @ConditionalOnProperty   → yml 配置开关(最最最常用!)
├── @ConditionalOnBean       → 容器里有没有某个 Bean
├── @ConditionalOnMissingBean→ 容器里没有某个 Bean 才装配(神器!)
├── @ConditionalOnClass      → 类路径下有没有某个 class
├── @ConditionalOnMissingClass→ 没有某个 class 才装配
├── @ConditionalOnExpression → SpEL 表达式随便写
├── @ConditionalOnJava       → JDK 版本判断
├── @ConditionalOnResource   → 有没有某个资源文件
├── @ConditionalOnCloudPlatform → 是不是在云上运行
├── @ConditionalOnWebApplication → 是不是 Web 项目
├── @ConditionalOnNotWebApplication → 不是 Web 项目
└── @ConditionalOnSingleCandidate → 同类型只有一个 Bean

2025 年真实项目最常用的 5 个(90%场景就这几个)

排名注解真实用法示例(直接抄)实际场景占比
1@ConditionalOnProperty“`java
@Bean
@ConditionalOnProperty(name = “feature.pay.enabled”, havingValue = “true”, matchIfMissing = false)
public AliPayService aliPay() { return new AliPayService(); }
“`50%
2@ConditionalOnMissingBean“`java
@ConditionalOnMissingBean(RedisTemplate.class)
@Bean
public RedisTemplate redisTemplate(…) { … }
“`25%
3@Profile“`java
@Profile(“dev”)
@Configuration
public class DevConfig { … }
“`15%
4@ConditionalOnClass“`java
@ConditionalOnClass(name = “com.zaxxer.hikari.HikariDataSource”)
@Bean
public HikariDataSource dataSource() { … }
“`8%
5@ConditionalOnExpression“`java
@ConditionalOnExpression(“${server.port} == 8080 or ${server.port} == 8081”)
“`2%

实战最强组合写法(大厂标配,直接抄进项目)

// 1. 开发环境用 H2 数据库,生产用 MySQL
@Profile("dev")
@Bean
public DataSource h2DataSource() { ... }

@Profile("!dev")
@Bean
public DataSource mysqlDataSource() { ... }

// 2. 只有配置了 redis.enabled=true 才装配 RedisTemplate
@Bean
@ConditionalOnProperty(prefix = "spring.redis", name = "enabled", havingValue = "true")
public RedisTemplate<String, Object> redisTemplate(...) { ... }

// 3. 项目没自己配 DataSource 才用 Spring Boot 的默认 Hikari
@Configuration
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfig { ... }

// 4. 只有类路径有 Kafka,才装配 KafkaTemplate
@ConditionalOnClass(KafkaTemplate.class)
@EnableKafka
@Configuration
public class KafkaAutoConfig { ... }

// 5. 生产环境才开启 Redisson 分布式锁
@Bean
@ConditionalOnProperty(name = "lock.type", havingValue = "redisson")
@Profile("prod")
public RedissonClient redissonClient() { ... }

面试终极 6 连问 + 标准答案(背完无敌)

  1. @ConditionalOnProperty 怎么写才最安全?
    答:三个参数全写!
   @ConditionalOnProperty(
       name = "feature.xxx.enabled",
       havingValue = "true",
       matchIfMissing = false   // 没配时不生效
   )
  1. @ConditionalOnMissingBean 是怎么工作的?
    答:Spring Boot 所有自动装配都靠它!它让用户可以轻松覆盖默认配置。
  2. @Profile 和 @ConditionalOnProperty 什么关系?
    答:@Profile 底层就是 @ConditionalOnProperty,
    @Profile("dev") 等价于 @ConditionalOnProperty(name="spring.profiles.active", havingValue="dev")
  3. 我想在本地开发时用假支付,线上用真支付,怎么写?
    答:
   @Bean
   @Profile("dev")
   public PayService fakePay() { return new FakePayService(); }

   @Bean
   @Profile("!dev")
   public PayService realPay() { return new AliPayService(); }
  1. Spring Boot 是怎么实现“开箱即用又能自定义”的?
    答:全靠 @ConditionalOnMissingBean + @ConditionalOnClass 组合拳!
  2. @Conditional 家族的执行顺序?
    答:在 BeanDefinition 注册完、实例化之前执行(比 @PostConstruct 早得多)。

终极记忆口诀(10 秒记住全部)

“有配置 OnProperty,没 Bean OnMissingBean,
有类 OnClass,没类 OnMissingClass,
开发用 Profile,复杂写 Expression,
Spring Boot 全靠 MissingBean 实现自动装配!”

背完这张图 + 5个最常用写法 + 口诀,
面试官问“Spring 条件装配怎么玩”,你直接甩代码 + 画图,
他当场就能给你发 offer!冲!

文章已创建 3017

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部