Spring Boot基于特定条件创建Bean例子 : ConditionalOnMissingBean

本文详细介绍了如何结合使用Spring Boot中的@ConditionalOnMissingBean和@Bean注解来实现Bean的条件化注入,确保只有特定名称或类型的Bean不存在于BeanFactory中时才创建指定的Bean。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结合使用注解@ConditionalOnMissingBean和@Bean,可以做到只有特定名称或者类型的Bean不存在于BeanFactory中时才创建某个Bean :

@Configuration
public class ConditionalOnMissingBeanConfig {

    @Bean
    public A beanA(){
        return new A(); // 无条件定义一个bean : beanA
    }
    
    @Bean
    @ConditionalOnMissingBean(name="beanA")
    public B beanB(){
	    // 如果 beanFactory 中存在一个名称为 beanA 的 bean,才定义bean : beanB;
		// 因为上面的方法已经定义了一个 beanA,所以这里 beanB定义并不会发生。
        return new B(); 
    }
    
    @Bean
    @ConditionalOnMissingBean(name="beanD")
    public C beanC(){
	    // 如果 beanFactory 中存在一个名称为 beanD的 bean,才定义bean : beanC;	    
        return new C(); 
    }
   
}

ConditionalOnMissingBean注解条件匹配所检查的bean定义仅限于spring boot 执行过程中application context截至当前所处理的那些bean,因此,强烈建议仅将 ConditionalOnMissingBean 使用于 auto-configuration 类。另外,如果一个候选 bean 需要在另外一个 auto-configuration 完成之后创建(或者不创建),那么需要确保该 ConditionalOnMissingBean 在那个 auto-configuration 完成之后执行。

注解 ConditionalOnMissingBean 的官方API文档

<think>嗯,用户想了解Spring Boot中的@ConditionalOn系列注解,具体包括@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnClass、@ConditionalOnMissingClass和@ConditionalOnProperty这些注解的功能和用法。我需要先回忆这些注解的作用,然后结合提供的引用内容来组织回答。 首先,@ConditionalOnBean和@ConditionalOnMissingBean应该和Bean的存在与否有关。根据引用[1]和[2],当使用@ConditionalOnBean时,只有在容器中存在指定的Bean才会创建当前Bean。比如在引用[2]的例子中,当ClassA被注入后,ClassB才会被注入。而@ConditionalOnMissingBean则相反,当容器中没有指定Bean时才生效。 接下来是@ConditionalOnClass和@ConditionalOnMissingClass,这些应该和类路径上是否存在某个类有关。引用[4]提到了@ConditionalOnClass和@ConditionalOnProperty,可能它们的用法类似,根据类是否存在来决定是否注册Bean。比如如果有某个类在类路径中,才会启用配置。 然后是@ConditionalOnProperty,这个应该和配置文件中的属性有关。引用[4]中的例子@ConditionalOnExpression("${my.controller.enabled:false}")可能和属性配置有关,不过@ConditionalOnProperty更直接,根据属性是否存在或特定的值来决定条件。 另外,引用[3]提到了其他几个@ConditionalOn注解,比如@ConditionalOnCloudPlatform、@ConditionalOnJava等,但用户的问题中没有提到这些,可能不需要详细展开,但可以作为相关知识提及。 需要整理每个注解的功能、使用场景和示例。比如@ConditionalOnBean用于依赖其他Bean的情况,确保某个Bean存在后才加载当前配置。@ConditionalOnMissingBean用于默认配置,当用户没有自定义Bean时才生效。@ConditionalOnClass用于自动配置,当某个类存在时才加载相关配置,比如数据库驱动。 要注意用户可能混淆这些注解的使用场景,比如何时使用type=和value=属性。引用[2]中的例子提到了使用type=的情况,可能需要说明这两种用法的区别。 此外,需要确保回答结构清晰,分点说明每个注解,并给出代码示例,帮助用户理解。同时,根据用户提供的引用内容,正确引用对应的引用标记,如[^1]、[^2]等。 最后,生成相关问题,可能需要包括这些注解的区别、组合使用、常见错误以及与其他注解的对比等。比如如何避免条件注解的循环依赖,或者如何根据属性控制Bean的注册。 总结一下,回答需要覆盖每个注解的功能、用法、示例,并正确引用提供的资料,最后生成相关问题供用户进一步学习。</think>### Spring Boot @ConditionalOn 系列注解详解 Spring Boot 的 `@ConditionalOn` 系列注解用于**根据特定条件动态控制 Bean 的加载**,常用于自动配置、依赖管理和环境适配。以下是核心注解的功能和用法: --- #### 1. @ConditionalOnBean 与 @ConditionalOnMissingBean - **功能**:根据容器中是否存在指定 Bean 来决定是否注册当前 Bean。 - `@ConditionalOnBean`:当容器中存在指定 Bean 时才生效。 - `@ConditionalOnMissingBean`:当容器中不存在指定 Bean 时才生效[^1][^2]。 - **典型场景**: - 自动配置类的依赖检查(如数据库连接池依赖数据源 Bean)。 - 提供默认实现,允许用户自定义覆盖。 - **示例**: ```java @Configuration public class MyConfig { // 仅当 DataSource Bean 存在时注册 JdbcTemplate @Bean @ConditionalOnBean(DataSource.class) public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } // 仅当 UserService Bean 不存在时注册默认实现 @Bean @ConditionalOnMissingBean public UserService defaultUserService() { return new DefaultUserService(); } } ``` --- #### 2. @ConditionalOnClass 与 @ConditionalOnMissingClass - **功能**:根据类路径中是否存在指定类来决定是否注册 Bean。 - `@ConditionalOnClass`:当类路径中存在指定类时生效。 - `@ConditionalOnMissingClass`:当类路径中不存在指定类时生效[^4]。 - **典型场景**: - 自动配置模块(如仅当 `RedisClient` 存在时启用 Redis 配置)。 - 适配不同环境或依赖库版本。 - **示例**: ```java @Configuration @ConditionalOnClass(RedisClient.class) // 检查 RedisClient 是否在类路径中 public class RedisAutoConfig { @Bean public RedisTemplate<String, Object> redisTemplate() { return new RedisTemplate<>(); } } ``` --- #### 3. @ConditionalOnProperty - **功能**:根据配置文件中的属性值(如 `application.properties`)控制 Bean 的注册。 - 支持检查属性是否存在、是否匹配特定值或默认值。 - **典型场景**: - 功能开关(如启用/禁用缓存、日志等)。 - 环境差异化配置(开发、测试、生产环境)。 - **示例**: ```java @Configuration @ConditionalOnProperty( prefix = "myapp.feature", name = "cache.enabled", havingValue = "true", // 当 myapp.feature.cache.enabled=true 时生效 matchIfMissing = false // 属性缺失时是否匹配(默认 false) ) public class CacheConfig { @Bean public CacheManager cacheManager() { return new EhCacheManager(); } } ``` --- #### 注解参数对比 | 注解 | 关键参数 | 作用范围 | |-------------------------|-------------------------|--------------------| | `@ConditionalOnBean` | `value`(Bean 类型) | Bean 容器 | | `@ConditionalOnClass` | `value`(类全限定名) | 类路径 | | `@ConditionalOnProperty`| `prefix`、`name`、`havingValue` | 配置文件属性 | --- #### 注意事项 1. **条件注解的优先级**:条件注解的检查发生在 Bean 定义阶段,需确保依赖的 Bean 或类已提前加载。 2. **循环依赖风险**:避免在相互依赖的 Bean 之间使用条件注解[^2]。 3. **组合使用**:可通过 `@Conditional` 组合多个条件,例如同时检查类和属性: ```java @Conditional({OnClassCondition.class, OnPropertyCondition.class}) ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值