当前位置: 首页 > article >正文

【@ConditionOnBean】

@ConditionOnBean的介绍与使用

@ConditionOnBean 是 Spring Boot 中的一种条件注解,用于在配置类或者组件上指定一个或多个 bean 的条件,只有当指定的 bean 存在于 Spring 容器中时,才会创建该配置类或者组件。

具体来说,@ConditionOnBean 可以在以下场景中使用:

配置类中的条件装配:
在配置类上使用 @Configuration 注解标注的类中,可以使用 @ConditionOnBean 指定一个或多个需要存在的 bean 的条件,只有当所有指定的 bean 都存在时,才会创建该配置类中定义的 bean。

自动配置类中的条件装配:
在自动配置类上使用 @ConditionalOnBean 注解可以实现自动配置的条件,只有当指定的 bean 存在时,才会触发自动配置类中定义的配置逻辑。

@ConditionOnBean 注解有以下常用属性:

value:指定一个或多个需要存在的 bean 的全限定类名,多个 bean 之间使用逗号分隔。
name:指定一个或多个需要存在的 bean 的名称,多个 bean 之间使用逗号分隔。
annotation:指定一个或多个需要存在的带有指定注解的 bean,多个注解之间使用逗号分隔。
havingValue:当 bean 的属性值与指定的值相等时,条件满足。
matchIfMissing:默认值为 true,表示当所有指定的 bean 都不存在时,条件仍然满足。

下面是一个使用 @ConditionOnBean 的例子:

@Configuration
@ConditionOnBean(name = "myDataSource", annotation = EnableTransactionManagement.class)
@EnableTransactionManagement(proxyTargetClass = true)
public class TransactionManagementAutoConfiguration {
    // ...
}

在上面的例子中,当名为 myDataSource 的 bean 存在,且存在一个带有 @EnableTransactionManagement 注解的 bean 时,才会创建 TransactionManagementAutoConfiguration 配置类,并启用事务管理功能。如果没有符合条件的 bean,该配置类就不会被创建。

另外,下面是一个更完整的示例,演示了如何使用 @ConditionOnBean 检查 DataSource 和 JdbcTemplate 是否存在,如果存在则创建一个使用 JdbcTemplate 的 DAO:

@Configuration
public class MyDaoAutoConfiguration {

    @Bean
    @ConditionOnBean({DataSource.class, JdbcTemplate.class})
    public MyDao myDao(JdbcTemplate jdbcTemplate) {
        return new MyDao(jdbcTemplate);
    }

}

在上面的例子中,@ConditionOnBean 注解的 value 属性指定了需要存在的 bean 的类型,即 DataSource.class 和 JdbcTemplate.class。只有当这两个 bean 都存在时,MyDao 才会被创建并注入 JdbcTemplate。如果没有符合条件的 bean,MyDao 就不会被创建。

加载顺序

在 Spring 应用程序中,Bean 的加载顺序非常重要,因为 Bean 之间可能会有依赖关系,如果依赖的 Bean 还未被加载,就会导致应用程序无法正常启动或运行。

当使用 @ConditionOnBean 注解时,如果多个 Bean 都满足条件,那么加载顺序就会变得非常重要,因为后续 Bean 的加载可能依赖于前面已经加载的 Bean。如果不正确地处理 Bean 的加载顺序,就可能导致应用程序无法正常工作。

为了解决这个问题,可以使用 @DependsOn 注解来显式地指定 Bean 的加载顺序。通过指定 @DependsOn 注解,可以确保某个 Bean 会在其他指定的 Bean 之后被加载。例如:

@Configuration
public class MyConfig {

    @Bean
    public MyBean1 myBean1() {
        return new MyBean1();
    }

    @Bean
    @DependsOn("myBean1")
    @ConditionalOnBean(MyBean1.class)
    public MyBean2 myBean2() {
        return new MyBean2();
    }
}

在上面的代码中,MyBean2 的加载依赖于 MyBean1 的存在,因此使用了 @DependsOn 注解来确保 MyBean1 先被加载。这样可以确保 Bean 的加载顺序正确,应用程序能够正常工作。

除了使用 @DependsOn 注解之外,还可以使用其他的 Bean 加载控制注解,例如 @Order 注解、@Priority 注解等,来控制 Bean 的加载顺序。不同的注解适用于不同的场景,具体可以根据实际情况选择使用。

加载优先级

当使用 @ConditionOnBean 注解来控制 Bean 加载顺序时,我们通常需要使用 @DependsOn 注解来显式地指定 Bean 的加载顺序,但是还有其他的注解可以用来控制 Bean 的加载顺序,下面介绍两个常用的注解。

@Order 注解

@Order 注解是 Spring 框架提供的用于控制 Bean 加载顺序的注解之一。使用该注解时,可以为 Bean 指定一个顺序值,顺序值越小的 Bean 会先被加载。例如:

@Component
@Order(1)
public class MyBean1 {
    // ...
}

@Component
@Order(2)
public class MyBean2 {
    // ...
}

在上面的代码中,MyBean1 的顺序值为 1,MyBean2 的顺序值为 2,因此 MyBean1 会先被加载,MyBean2 会在其后被加载。

需要注意的是,如果没有指定 @Order 注解的 Bean,它们的顺序值默认为 Ordered.LOWEST_PRECEDENCE,也就是最低优先级,会最后被加载。

@Priority 注解

@Priority 注解是 Java 标准库提供的用于控制对象加载顺序的注解之一。该注解可以用于任何对象,并且可以为对象指定一个优先级,优先级越高的对象会先被加载。例如:

@Priority(1)
public class MyObject1 {
    // ...
}

@Priority(2)
public class MyObject2 {
    // ...
}

在上面的代码中,MyObject1 的优先级为 1,MyObject2 的优先级为 2,因此 MyObject1 会先被加载,MyObject2 会在其后被加载。

需要注意的是,@Priority 注解并不是 Spring 框架提供的注解,因此在使用该注解时需要确保目标环境支持该注解。另外,如果没有指定 @Priority 注解的对象,它们的优先级默认为 0,也就是最低优先级,会最后被加载。


http://www.kler.cn/a/6315.html

相关文章:

  • [linux]基础IO
  • [课程][原创]yolov7目标检测封装成类调用
  • 手写vuex4源码(二)组件install逻辑
  • Android ART虚拟机 GC的各种类型
  • 分享一个国内可用的免费ChatGPT网站
  • 15_I.MX6ULL_LCD显示原理
  • [C++]类与对象上篇
  • DFSBFS总结
  • 《高等工程数学》习题卷(一)
  • 蓝桥杯训练day5
  • 【深度学习】基于Hough变化的答题卡识别(Matlab代码实现)
  • Text to image论文精读GigaGAN: 生成对抗网络仍然是文本生成图像的可行选择
  • day30 ● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独
  • OBProxy 路由策略与使用运维-使用和运维
  • c++全排列 next_permutation()函数
  • 字节测试总监,让我们用这份《测试用例规范》,再也没加班过
  • 【故障诊断】基于最小熵反卷积、最大相关峰度反卷积和最大二阶环平稳盲反卷积等盲反卷积方法在机械故障诊断中的应用研究(Matlab代码实现)
  • vue尚品汇商城项目-day03【20.获取Banner轮播图的数据+21.使用swiper轮播图插件】
  • 【ZGC】为什么初始标记需要STW(stop the world) ?
  • 操作系统-AOSOA