浅谈SpringBoot中的@Conditional注解的使用
作者:roseduan 发布时间:2021-12-07 16:47:04
概述
Spring boot 中的 @Conditional 注解是一个不太常用到的注解,但确实非常的有用,我们知道 Spring Boot 是根据配置文件中的内容,决定是否创建 bean,以及如何创建 bean 到 Spring 容器中,而 Spring boot 自动化配置的核心控制,就是 @Conditional 注解。
@Conditional 注解是 Spring 4.0 之后出的一个注解,与其搭配的一个接口是 Condition,@Conditional 注解会根据具体的条件决定是否创建 bean 到容器中,接下来看看 @Conditional 注解的简单使用。
1. @Conditional 和 Condition 接口搭配使用
这里需要实现的功能是,我们根据配置文件中的具体内容,来决定是否创建 bean,首先我们在 application.yml 中加上一个自定义配置:
这里我们决定,这个配置中包含了 product 这个字符串的时候,才创建 bean。Product 是我自己随便创建的一个实体类,你可以自行创建。
新建一个类 ProductCondition
,内容如下:
public class ProductCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//从配置文件中获取属性
String property = conditionContext.getEnvironment().getProperty("create.bean");
if (property != null){
return property.contains("product");
}
else {
return false;
}
}
}
这个类实现了 Condition 接口,这个接口只有一个方法,我们从配置文件中获取刚才创建的自定义配置,如果配置中包含了 product 这个字符串,就会返回 true。
接下来创建一个配置类 ProductConfig,内容如下:
@Configuration
public class ProductConfig {
@Conditional(ProductCondition.class)
@Bean(name = "product")
public Product createProd(){
return Product.builder().id(12312).categoryId(12).
productName("Mac Book Pro").productImg("prod.png")
.productPrice(18000).build();
}
}
我们在创建的 bean 方法前面加上了 @Conditional 注解,判断的标准是刚才的 ProductCondition,如果是 true,则创建 bean,否则不创建。我们写一个测试类,来测试一下 bean 是否被创建了。测试代码如下:
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class ProductConfigTest {
@Test
public void createProd() {
try {
Product product = SpringContextUtil.getBean("product", Product.class);
if (product != null){
System.out.println("创建了 bean : " + product.toString());
}
}
catch (Exception e){
log.info("发生异常,{}", e.getMessage());
System.out.println("没有创建 bean");
}
}
}
运行测试代码,发现 bean 已经创建了:
如果把 application.yml 中的配置改一下,不包含 product 这个字符串,那么返回的是 false,bean 则不会被创建,你可以试一下。
2. @ConditionalOnClass 的使用
这个注解的属性可以跟上一个类的完整路径或者是类的 Class 对象,如果类存在,则会创建 bean,例如下面的例子:
@Configuration
public class ProductConfig {
@ConditionalOnClass(name = "com.roseduan.demo.entity.Product")
@Bean(name = "product")
public Product createProd(){
return Product.builder().id(12312).categoryId(12).
productName("Mac Book Pro").productImg("prod.png")
.productPrice(18000).build();
}
}
这个路径下面的实体类 Product 是存在的,所以会创建 bean,如果是一个不存在的类,则不会创建。
3. @ConditionalOnProperty 的使用
这个注解可以直接从配置文件中获取属性,然后做为是否创建 bean 的依据。例如我们在 application.yml 中添加一个自定义配置:
ProductConfig 类的内容是这样的:
@Configuration
public class ProductConfig {
@ConditionalOnProperty(value = "create.product.bean")
@Bean(name = "product")
public Product createProd(){
return Product.builder().id(12312).categoryId(12).
productName("Mac Book Pro").productImg("prod.png")
.productPrice(18000).build();
}
}
这里使用了 @ConditionalOnProperty 注解,从文件中读取配置,因为我们设置的是 true,所以这个 bean 会被创建,如果设置成 false,则 bean 不会被创建,你可以自己试一下。根据这个特性,我们可以给一些特定的配置加上一个开关,非常方便控制。
这里我只是列举了几个常用的注解,你可以查看官方文档,里面有更详细的说明:
参考文档:Spring Boot 官网文档
来源:https://segmentfault.com/a/1190000018777937


猜你喜欢
- 不知不觉这个春节也已经过完了,遗憾家里没网,没能及时给大家送上祝福,今天回到深圳,明天就要上班了,小伙伴们是不是和我一样呢?今天讲的是一个大
- 前言在H5火热的时代,许多框架都出了底部弹窗的控件,在H5被称为弹出菜单ActionSheet,今天我们也来模仿一个ios的底部弹窗,取材于
- 在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock.R
- 昨天在与对端系统调接口的时候,对端系统对我们传过去的json串老是处理不了,后来查原因是应为我们传过去的json串里有json对象数组,因为
- 实现从数据库中动态获取对应的List集合,并在Easyui的combobox中显示出来。实现的效果如下:1、数据库的表设计如图所示2、数据库
- Android Q 禁止获取 IMEI 和设备序列号;官方的解决方案是这样:https://developer.android.com/tr
- 自定义Repository接口要定义一个repository接口,你首先需要自定义一个实体类专用的Repository接口。该接口必须扩展
- 23种设计模式第十九篇:java责任链模式定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条
- 在Android程序开发中我们经常遇到四种数据存储方式,每种存储方式都各有不同;以下我分别列举了Android开发中的不同存储方式的特点一,
- 经常看到同事这样写代码:DataSet QueryDB(){ DataSet ds=null;  
- Volatile关键字的作用主要有如下两个:1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。2. 顺序一致性
- SpringMVC文件上传中要解决的问题一、中文文件名编码问题通过过滤器解决二、文件位置存储问题放在当前项目下,作为静态资源,这样可以通过U
- 一、日志工具功能封装Debug类,需要实现功能:1.控制所有日志是否打印;2.除了Log,Warning,Error外,给更多日志种类(不同
- 先看看常规的隐藏状态栏的方法:方法一:@Overrideprotected void onCreate(Bundle savedInstan
- 详解Java对象的强、软、弱和虚引用+ReferenceQueue一、强引用(StrongReference)强引用是使用最普遍的引用。如果
- 本文实例讲述了Android实现的秒表计时器。分享给大家供大家参考,具体如下:package com.liu.time;import jav
- 本文实例讲述了Android开发高级组件之自动完成文本框(AutoCompleteTextView)用法。分享给大家供大家参考,具体如下:通
- Java二维数组Java 语言中提供的数组是用来存储固定大小的同类型元素。1.二维数组初始化和声明数组变量的声明,和创建数组可以用一条语句完
- 阿姆斯特朗数阿姆斯特朗数是一个数字,等于每个数字的幂乘以总位数。 例如,诸如0、1、153、370、371和407、1634、8208、94
- Android 动画实现几种方案在 Android 的 FrameWork 中,为我们提供三种动画的实现方式:逐帧(Frame)动画、视图/