Spring Boot 中的 @ConditionalOnBean 注解详解

06-02 259阅读

Spring Boot 中的 @ConditionalOnBean 注解详解

    • 1. 前言
    • 2. `@ConditionalOnBean` 作用与基本用法
      • 2.1 `@ConditionalOnBean` 的作用
      • 2.2 基本用法
        • 示例:当 `DataSource` Bean 存在时,才创建 `MyService` Bean
        • 3. `@ConditionalOnBean` 详解
          • 3.1 `value` 和 `type` 属性(指定 Bean 类型)
          • 3.2 `name` 属性(指定 Bean 名称)
          • 3.3 `annotation` 属性(指定 Bean 需要标注的注解)
          • 3.4 `search` 属性(搜索范围)
          • 4. `@ConditionalOnBean` 使用场景
            • 场景 1:按需加载数据库相关 Bean
            • 场景 2:启用某些自动配置
            • 场景 3:可选依赖的组件
            • 5. `@ConditionalOnBean` vs `@ConditionalOnMissingBean`
            • 6. 结论
              • 总结:

                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)

                        你在项目中用过 @ConditionalOnBean 吗?欢迎留言分享你的经验!🚀

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码