本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
该注解的作用是可以通过配置文件中的属性值来判定 configuration 是否被注入,这样就可以灵活的配置组件的启用。
先上注解源码:
package org.springframework.boot.autoconfigure.condition;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Conditional;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({OnPropertyCondition.class})
public @interface ConditionalOnProperty {
/**
* 该属性与下面的 name 属性不可同时使用,
* 当value所对应配置文件中的值为false时,注入不生效,不为fasle注入生效
* value有多个值时,只要有一个值对应为false,则注入不成功
*/
String[] value() default {};
/**
* 配置文件中key的前缀,可与value 或 name 组合使用
*/
String prefix() default "";
/**
* 与 value 作用一致
*/
String[] name() default {};
/**
* 与value 或 name 组合使用,只有当value 或 name 对应的值与havingValue的值相同时,注入生效
*/
String havingValue() default "";
/**
* 该属性为true时,配置文件中缺少对应的value或name的对应的属性值,也会注入成功
*/
boolean matchIfMissing() default false;
}
在源码中添加了比较详细的注释,在下面的测试示例中,会让大家更加深刻的理解它的使用。
配置文件这里采用 properties 格式进行测试,当然也可以使用 yml 格式,这里就不再列举。
我们从简单到复杂逐步进行举例说明:
1、name 属性
配置类代码如下:
@Component
@EnableScheduling
@ConditionalOnProperty(name = "timer.enabled")
public class ConditionalOnPropertyTest {
private static Logger logger = LogManager.getLogger(ConditionalOnPropertyTest.class);
@Scheduled(cron = "*/5 * * * * ?")
public void test(){
logger.info("定时器执行....");
}
}
各种配置结果如下:
timer.enabled=false //无效
timer.enabled=true //有效
timer.enabled=1111 //有效
timer.enabled=null //有效
这里说明一点,只要配置的值是非 false 都有效,这也和最前面的注释一致。下面我们从这个基本的配置进行衍生
2、value 属性
把 name 属性换成 value 属性,测试结果和 name 一样,说明他们具有相同的作用,后面就只贴关键代码了
@ConditionalOnProperty(value = "timer.enabled")
如果同时配置了 name 属性和 value 属性,我们试试看
@ConditionalOnProperty(value = "timer.open", name = "timer.enabled")
结果启动报错:
Caused by: java.lang.IllegalStateException: The name and value attributes of @ConditionalOnProperty are exclusive
这就是验证了一点,name 属性和 value 属性不能同时使用。
3、prefix 属性
我们加上 prefix 前缀属性:
@ConditionalOnProperty(prefix = "timer", name = "enabled")
作用和把 name 直接命名为:timer.enabled 一样,prefix 可以和 name 或者 value 属性组合使用,用. 连接,那么一般为了方便管理,通常都会用多层级的方式进行组合,下面都统一用前缀组合的方式进行分析
4、havingValue 属性
下面介绍 havingValue 属性,即只有当 name 或者 value 属性的值与 havingValue 属性完全相同时,注入才有效,示例如下:
@ConditionalOnProperty(prefix = "timer", name = "enabled",havingValue = "open")
timer.enabled=open
5、matchIfMissing 属性
如果该属性为 true,表示 name 或者 value 没有配置对应属性也能注入,默认 matchIfMissing 属性的值是 false,所以要求为 false 的时候就可以不配置该值了,和前面的示例一样
注解配置如下:
@ConditionalOnProperty(prefix = "timer", name = "enabled",havingValue = "open",matchIfMissing = true)
结果如下:
timer.enabled=333 //无效
timer.enabled=open //有效
不配置 //有效
通过上面的讲解,详细大家对这四个属性的作用已经非常清楚了。
6、name 或者 value 为多个值的情况
@ConditionalOnProperty(prefix = "timer", name = {"enabled","isopen"},havingValue = "open")
这就要求 name 的两个值都必须有并且为 open
timer.enabled=open //只有一个无效
timer.enabled=open
timer.isopen=open //有效
timer.enabled=open
timer.isopen=111 //无效
不配置 //无效
如果加上 matchIfMissing 属性,表示可以缺少
@ConditionalOnProperty(prefix = "timer", name = {"enabled","isopen"},havingValue = "open",matchIfMissing = true)
验证
不配置 // 有效
timer.enabled=open // 有效
timer.enabled=open
timer.isopen=open // 有效
timer.enabled=open
timer.isopen=111// 无效
timer.enabled=111// 无效