SpringBoot中的条件注解使用示例详解

 更新时间:2025年08月23日 10:22:35   作者:寒士obj  
SpringBoot条件注解用于动态控制Bean创建与配置加载,基于@Conditional机制,支持按类、Bean、属性等条件判断,广泛应用于多数据源等场景,提升应用灵活性与智能化,接下来通过本文给大家讲解SpringBoot中的条件注解使用,感兴趣的朋友一起看看吧

前言

在SpringBoot开发中,我们经常会遇到这样的场景:某些Bean只有在特定条件下才需要被创建,或者根据不同的环境加载不同的配置。SpringBoot的条件注解就是为了解决这类问题而设计的。

什么是条件注解

条件注解是SpringBoot提供的一套机制,允许我们根据特定条件来决定是否创建Bean、加载配置或执行某些逻辑。这些注解基于Spring 4.0引入的@Conditional注解,SpringBoot在此基础上扩展了更多实用的条件注解。

核心原理

所有的条件注解都基于@Conditional注解,该注解需要指定一个Condition接口的实现类。Condition接口只有一个方法:

public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

当Spring容器加载Bean时,会调用这个方法来判断条件是否满足。如果返回true,则创建Bean;如果返回false,则跳过。

常用条件注解详解

1. @ConditionalOnClass和@ConditionalOnMissingClass

这两个注解用于检查类路径中是否存在指定的类。

@Configuration
public class DatabaseConfig {
    // 当类路径中存在DataSource类时才创建这个Bean
    @Bean
    @ConditionalOnClass(DataSource.class)
    public DataSource dataSource() {
        return new HikariDataSource();
    }
    // 当类路径中不存在Redis相关类时才创建内存缓存
    @Bean
    @ConditionalOnMissingClass("org.springframework.data.redis.core.RedisTemplate")
    public CacheManager memoryCache() {
        return new ConcurrentMapCacheManager();
    }
}

2. @ConditionalOnBean和@ConditionalOnMissingBean

这两个注解根据Spring容器中是否存在指定的Bean来决定是否创建。

@Configuration
public class ServiceConfig {
    // 当容器中存在UserRepository Bean时才创建UserService
    @Bean
    @ConditionalOnBean(UserRepository.class)
    public UserService userService(UserRepository userRepository) {
        return new UserServiceImpl(userRepository);
    }
    // 当容器中不存在CacheManager时才创建默认的
    @Bean
    @ConditionalOnMissingBean(CacheManager.class)
    public CacheManager defaultCacheManager() {
        return new NoOpCacheManager();
    }
}

3. @ConditionalOnProperty

根据配置属性来决定是否创建Bean,这是最常用的条件注解之一。

@Configuration
public class FeatureConfig {
    // 当spring.feature.enabled=true时才启用这个功能
    @Bean
    @ConditionalOnProperty(
        prefix = "spring.feature",
        name = "enabled",
        havingValue = "true",
        matchIfMissing = false // 默认false,即属性不存在时不匹配
    )
    public FeatureService featureService() {
        return new FeatureServiceImpl();
    }
}

应用场景:多数据源配置

@Configuration
public class DataSourceConfig {
    @Primary
    @Bean
    @ConditionalOnProperty(name = "app.datasource.primary.enabled", havingValue = "true")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create()
            .url("jdbc:mysql://localhost:3306/primary")
            .build();
    }
    @Bean
    @ConditionalOnProperty(name = "app.datasource.secondary.enabled", havingValue = "true")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create()
            .url("jdbc:mysql://localhost:3306/secondary")
            .build();
    }
}

在SpringBoot自动配置中的核心作用

SpringBoot的自动配置是其最核心的特性之一,而条件注解正是自动配置得以智能化的关键所在。让我们深入了解条件注解在自动配置中是如何发挥作用的。

自动配置的工作原理

SpringBoot通过spring.factories文件定义了所有的自动配置类,启动时会加载这些配置。但是,并不是所有的配置都应该被激活,这就需要条件注解来控制。

# META-INF/spring.factories示例
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration

经典自动配置示例分析

让我们看看SpringBoot内置的一些自动配置是如何使用条件注解的:

  1. RedisAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)  // Redis类存在时才配置
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")  // 用户没有自定义时才创建
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }
}
  1. DataSourceAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "javax.sql.DataSource")  // 没有数据源时才自动配置
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
         DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {
    @Configuration(proxyBeanMethods = false)
    @Conditional(EmbeddedDatabaseCondition.class)  // 自定义条件判断
    @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
    @Import(EmbeddedDataSourceConfiguration.class)
    protected static class EmbeddedDatabaseConfiguration {
    }
    @Configuration(proxyBeanMethods = false)
    @Conditional(PooledDataSourceCondition.class)
    @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
    @Import({ HikariConfiguration.class, TomcatConfiguration.class,
             DbcpConfiguration.class, OracleUcpConfiguration.class,
             GenericConfiguration.class, DataSourceJmxConfiguration.class })
    protected static class PooledDataSourceConfiguration {
    }
}

总结

SpringBoot的条件注解是一个非常强大的特性,它让我们能够构建更加灵活和智能的应用程序。通过合理使用这些注解,不仅能让我们写出更优雅的代码,也能让我们的应用在面对不同场景时表现得更加智能。希望这篇文章能帮助大家更好地理解和使用SpringBoot的条件注解。

到此这篇关于SpringBoot中的条件注解的文章就介绍到这了,更多相关SpringBoot条件注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • @Scheduled中的参数及Cron时间表达式用法详解

    @Scheduled中的参数及Cron时间表达式用法详解

    在SpringBoot中使用@Scheduled注解设置定时任务,可设置fixedDelay、fixedRate、initialDelay和cron参数,首句概括,后续分条列出参数解释和Cron表达式格式,最后给出示例
    2026-05-05
  • java模拟实现微信红包算法

    java模拟实现微信红包算法

    这篇文章主要为大家详细介绍了java实现模拟微信红包算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • MapStruct @Mapping注解之处理映射中的Null值方式

    MapStruct @Mapping注解之处理映射中的Null值方式

    这篇文章主要介绍了MapStruct @Mapping注解之处理映射中的Null值方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • 你知道将Bean交给Spring容器管理有几种方式(推荐)

    你知道将Bean交给Spring容器管理有几种方式(推荐)

    Spring核心是 IOC 和 AOP ,我们在Spring项目中,我们需要将Bean交给Spring容器,也就是IOC管理,这样你才可以使用注解来进行依赖注入,这篇文章主要介绍了你知道将Bean交给Spring容器管理有几种方式,需要的朋友可以参考下
    2022-10-10
  • 最新IntelliJ IDEA 2022配置 Tomcat 8.5 的详细步骤演示

    最新IntelliJ IDEA 2022配置 Tomcat 8.5 的详细步骤演示

    这篇文章主要介绍了IntelliJ IDEA 2022 详细配置 Tomcat 8.5 步骤演示,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • Spring 异常处理的各种姿势总结

    Spring 异常处理的各种姿势总结

    这篇文章主要介绍了Spring 异常处理,总结分析了Spring 异常处理的各种常见操作技巧与相关使用注意事项,需要的朋友可以参考下
    2020-05-05
  • mybatis条件构造器(EntityWrapper)的使用方式

    mybatis条件构造器(EntityWrapper)的使用方式

    这篇文章主要介绍了mybatis条件构造器(EntityWrapper)的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java高级语法学习之反射详解

    Java高级语法学习之反射详解

    java的泛型和反射机制一直很难理解和应用,下面这篇文章主要给大家介绍了关于Java高级语法学习之反射的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • Intellij idea使用Statistic统计代码行数的方法

    Intellij idea使用Statistic统计代码行数的方法

    这篇文章主要介绍了Intellij idea使用Statistic统计代码行数的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Java 基于TCP Socket 实现文件上传

    Java 基于TCP Socket 实现文件上传

    这篇文章主要介绍了Java 基于TCP Socket 实现文件上传的示例代码,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-12-12

最新评论