SpringBoot中@ConditionalOnBean注解的具体使用

 更新时间:2025年06月26日 09:17:00   作者:weixin_98543211  
本文主要介绍了SpringBoot中@ConditionalOnBean注解的具体使用,用于根据是否存在指定Bean动态注册Bean,支持类型、名称、注解及搜索范围控制,常见于按需加载、自动配置和可选依赖场景,与@ConditionalOnMissingBean形成条件对立

1. 前言

在 Spring Boot 中,条件注解(Conditional 注解) 是一种强大的功能,允许我们根据某些条件动态地注册或跳过特定的 Bean。其中,@ConditionalOnBean 是最常用的条件注解之一,它的作用是:当 Spring 容器中存在指定的 Bean 时,当前 Bean 才会被注册

本篇文章将详细介绍 @ConditionalOnBean 的使用场景、原理,并提供多个示例帮助理解。

2. @ConditionalOnBean 作用与基本用法

2.1 @ConditionalOnBean 的作用

@ConditionalOnBean 主要用于以下场景:

  • 按需加载 Bean:只有在某个 Bean 存在时,另一个 Bean 才会被创建。
  • 模块化设计:某些功能模块需要依赖特定 Bean 才能启用,例如 仅当某个组件存在时,自动配置才会生效
  • 避免 Bean 冲突:如果某个 Bean 依赖其他 Bean,则可使用 @ConditionalOnBean 确保它不会因缺少依赖而加载失败。

2.2 基本用法

示例:当 DataSource Bean 存在时,才创建 MyService Bean
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class MyConfig {

    @Bean
    public DataSource dataSource() {
        // 这里模拟 DataSource 实例,实际可用 HikariDataSource、Druid 等
        return new FakeDataSource();
    }

    @Bean
    @ConditionalOnBean(DataSource.class)  // 仅当 DataSource 存在时,才创建 MyService
    public MyService myService() {
        return new MyService();
    }
}

class MyService {
    public MyService() {
        System.out.println("MyService 被创建");
    }
}

class FakeDataSource implements DataSource {
    // 这里可以模拟 DataSource 方法
}

执行结果

MyService 被创建

如果 dataSource() 方法被注释掉,则 MyService 不会被创建。

3. @ConditionalOnBean 详解

@ConditionalOnBean 提供了多个属性,可以更加灵活地控制 Bean 的创建。

3.1 value 和 type 属性(指定 Bean 类型)

用于指定某种类型的 Bean 存在时,当前 Bean 才会被注册。

@Bean
@ConditionalOnBean(value = DataSource.class)  // 仅当 DataSource 存在时生效
public MyRepository myRepository() {
    return new MyRepository();
}

等效于:

@Bean
@ConditionalOnBean(type = "javax.sql.DataSource")  // 使用全限定类名
public MyRepository myRepository() {
    return new MyRepository();
}

区别

  • value:直接使用 Class 类型,编译时检查更安全。
  • type:使用字符串,可用于避免某些类找不到(如可选依赖)。

3.2 name 属性(指定 Bean 名称)

用于 指定某个 Bean 名称是否存在 来决定当前 Bean 是否加载。

@Bean
@ConditionalOnBean(name = "customBean")  // 仅当名为 customBean 的 Bean 存在时注册
public MyComponent myComponent() {
    return new MyComponent();
}

3.3 annotation 属性(指定 Bean 需要标注的注解)

可以指定某些 Bean 是否包含特定注解,如果包含,则当前 Bean 才会被注册。

@Bean
@ConditionalOnBean(annotation = Repository.class)  // 仅当存在 @Repository 注解的 Bean 时生效
public MyService myService() {
    return new MyService();
}

3.4 search 属性(搜索范围)

默认情况下,@ConditionalOnBean 只会在 当前应用上下文 中查找 Bean,而不会查找 父上下文(即 Spring Boot 的 ApplicationContext 层级)。

search 选项可以指定搜索范围:

  • ALL:在所有父子 ApplicationContext 中搜索。
  • CURRENT(默认):仅搜索当前 ApplicationContext
@Bean
@ConditionalOnBean(value = DataSource.class, search = SearchStrategy.ALL) // 在所有上下文中搜索
public MyService myService() {
    return new MyService();
}

4. @ConditionalOnBean 使用场景

场景 1:按需加载数据库相关 Bean

如果应用程序中 使用了数据库,则提供一个 DatabaseService,否则不创建:

@Bean
@ConditionalOnBean(DataSource.class)
public DatabaseService databaseService() {
    return new DatabaseService();
}

场景 2:启用某些自动配置

Spring Boot 的 spring-boot-autoconfigure 模块大量使用 @ConditionalOnBean 来控制自动配置。例如:

  • 只有当 DispatcherServlet 存在时,Spring MVC 相关的自动配置才会生效。
@Configuration
@ConditionalOnBean(DispatcherServlet.class)
public class MvcAutoConfiguration {
    // 仅当 DispatcherServlet 存在时,Spring MVC 配置生效
}

场景 3:可选依赖的组件

有时,某些功能是可选的,比如当 Redis 组件存在时,才创建缓存管理器:

@Bean
@ConditionalOnBean(name = "redisTemplate")  // 只有当 redisTemplate 存在时才加载
public CacheManager cacheManager() {
    return new RedisCacheManager();
}

5. @ConditionalOnBean vs @ConditionalOnMissingBean

注解作用
@ConditionalOnBean当指定 Bean 存在时,才注册当前 Bean
@ConditionalOnMissingBean当指定 Bean 不存在时,才注册当前 Bean

示例:

@Bean
@ConditionalOnMissingBean(DataSource.class)  // 仅当 DataSource 不存在时才创建
public DataSource defaultDataSource() {
    return new DefaultDataSource();
}

6. 结论

在 Spring Boot 中,@ConditionalOnBean 可以帮助我们根据 是否存在特定 Bean动态注册 Bean,广泛用于 按需加载、自动配置 等场景。

总结:

✅ 指定 Bean 类型:@ConditionalOnBean(DataSource.class)
✅ 指定 Bean 名称:@ConditionalOnBean(name = "customBean")
✅ 指定 Bean 注解:@ConditionalOnBean(annotation = Repository.class)
✅ 搜索范围:@ConditionalOnBean(search = SearchStrategy.ALL)

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

相关文章

  • SpringBoot3实现上传图片并返回路径让前端显示图片

    SpringBoot3实现上传图片并返回路径让前端显示图片

    这篇文章主要介绍了SpringBoot3实现上传图片并返回路径让前端显示图片,文中通过图文和代码讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-12-12
  • springcloud feign调其他微服务时参数是对象的问题

    springcloud feign调其他微服务时参数是对象的问题

    这篇文章主要介绍了springcloud feign调其他微服务时参数是对象的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Maven默认使用JDK1.5的问题及解决方案

    Maven默认使用JDK1.5的问题及解决方案

    这篇文章主要介绍了Maven默认使用JDK1.5的问题及解决方案,本文给大家分享两种方式,通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • Mybatis第三方PageHelper分页插件的使用与原理

    Mybatis第三方PageHelper分页插件的使用与原理

    提到插件相信大家都知道,插件的存在主要是用来改变或者增强原有的功能,MyBatis中也一样,下面这篇文章主要给大家介绍了关于Mybatis第三方PageHelper分页插件的使用与原理,需要的朋友可以参考下
    2022-02-02
  • Java的动态代理模式之Cglib代理详解

    Java的动态代理模式之Cglib代理详解

    这篇文章主要介绍了Java的动态代理模式之Cglib代理详解,Cglib代理也叫作 子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展, 有些书也将Cglib代理归属到动态代理,需要的朋友可以参考下
    2023-11-11
  • Java中sharding-jdbc 绑定表的实现

    Java中sharding-jdbc 绑定表的实现

    绑定表是 ShardingSphere-JDBC 解决跨库表关联查询的核心机制,通过强制分片键和算法一致的表路由到同一物理库,实现高效本地关联,适用于大表之间的关联场景,避免了全局表的存储冗余,下面就来详细的介绍一下如何使用,感兴趣的可以了解一下
    2026-03-03
  • Java构造代码块,静态代码块原理与用法实例分析

    Java构造代码块,静态代码块原理与用法实例分析

    这篇文章主要介绍了Java构造代码块,静态代码块,结合实例形式分析了Java构造代码块,静态代码块的功能、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • 创建网关项目(Spring Cloud Gateway)过程详解

    创建网关项目(Spring Cloud Gateway)过程详解

    这篇文章主要介绍了创建网关项目(Spring Cloud Gateway)过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 分析讲解Java Random类里的种子问题

    分析讲解Java Random类里的种子问题

    Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字
    2022-05-05
  • spring boot 学习笔记(入门篇)

    spring boot 学习笔记(入门篇)

    ing Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。这篇文章给大家带来了spring boot 入门学习笔记,需要的朋友参考下
    2018-02-02

最新评论