springboot 注解说明(@ConditionalOnProperty)
程序员文章站
2024-01-25 08:41:52
springboot注解说明(@ConditionalOnProperty)...
springboot 注解说明(@ConditionalOnProperty)
应用:根据配置文件的属性决定是否将类注册为bean
**********************
相关类与注解
@ConditionalOnProperty:标注在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({OnPropertyCondition.class})
public @interface ConditionalOnProperty {
String[] value() default {};
String prefix() default "";
String[] name() default {};
String havingValue() default "";
boolean matchIfMissing() default false;
}
说明:value与name等效,同时配置时,优先使用value;
匹配的key:prefix+"."+name,
若含有key,且设置了havingValue,若key对应的value=havingvalue,则匹配,若value与havingValue不等,则不匹配
若含有key,且没有设置havingValue,若key对应的value不为false,则匹配,若value为false,则不匹配
如不包含key,且设置了matchingIfMissing=true,则匹配,若matchingIfMissing=false,则不匹配
@Conditional
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value(); //继承condition的类数组
}
Condition
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
OnPropertyCondition
@Order(-2147483608)
class OnPropertyCondition extends SpringBootCondition {
OnPropertyCondition() {
}
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取匹配结果
List<AnnotationAttributes> allAnnotationAttributes = this.annotationAttributesFromMultiValueMap(metadata.getAllAnnotationAttributes(ConditionalOnProperty.class.getName()));
List<ConditionMessage> noMatch = new ArrayList();
List<ConditionMessage> match = new ArrayList();
Iterator var6 = allAnnotationAttributes.iterator();
while(var6.hasNext()) {
AnnotationAttributes annotationAttributes = (AnnotationAttributes)var6.next();
ConditionOutcome outcome = this.determineOutcome(annotationAttributes, context.getEnvironment());
(outcome.isMatch() ? match : noMatch).add(outcome.getConditionMessage());
}
if (!noMatch.isEmpty()) {
return ConditionOutcome.noMatch(ConditionMessage.of(noMatch));
} else {
return ConditionOutcome.match(ConditionMessage.of(match));
}
}
private List<AnnotationAttributes> annotationAttributesFromMultiValueMap(MultiValueMap<String, Object> multiValueMap) {
//将属性转换为List<AnnotationAttributes>
List<Map<String, Object>> maps = new ArrayList();
multiValueMap.forEach((key, value) -> {
for(int i = 0; i < value.size(); ++i) {
Object map;
if (i < maps.size()) {
map = (Map)maps.get(i);
} else {
map = new HashMap();
maps.add(map);
}
((Map)map).put(key, value.get(i));
}
});
List<AnnotationAttributes> annotationAttributes = new ArrayList(maps.size());
Iterator var4 = maps.iterator();
while(var4.hasNext()) {
Map<String, Object> map = (Map)var4.next();
annotationAttributes.add(AnnotationAttributes.fromMap(map));
}
return annotationAttributes;
}
private ConditionOutcome determineOutcome(AnnotationAttributes annotationAttributes, PropertyResolver resolver) {
OnPropertyCondition.Spec spec = new OnPropertyCondition.Spec(annotationAttributes);
List<String> missingProperties = new ArrayList();
List<String> nonMatchingProperties = new ArrayList();
spec.collectProperties(resolver, missingProperties, nonMatchingProperties);
if (!missingProperties.isEmpty()) {
return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).didNotFind("property", "properties").items(Style.QUOTE, missingProperties));
} else {
return !nonMatchingProperties.isEmpty() ? ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).found("different value in property", "different value in properties").items(Style.QUOTE, nonMatchingProperties)) : ConditionOutcome.match(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).because("matched"));
}
}
private static class Spec {
private final String prefix;
private final String havingValue;
private final String[] names;
private final boolean matchIfMissing;
Spec(AnnotationAttributes annotationAttributes) {
String prefix = annotationAttributes.getString("prefix").trim();
if (StringUtils.hasText(prefix) && !prefix.endsWith(".")) {
prefix = prefix + ".";
}
this.prefix = prefix;
this.havingValue = annotationAttributes.getString("havingValue");
this.names = this.getNames(annotationAttributes);
this.matchIfMissing = annotationAttributes.getBoolean("matchIfMissing");
}
private String[] getNames(Map<String, Object> annotationAttributes) {
String[] value = (String[])((String[])annotationAttributes.get("value"));
String[] name = (String[])((String[])annotationAttributes.get("name"));
Assert.state(value.length > 0 || name.length > 0, "The name or value attribute of @ConditionalOnProperty must be specified");
Assert.state(value.length == 0 || name.length == 0, "The name and value attributes of @ConditionalOnProperty are exclusive");
return value.length > 0 ? value : name;
} //name与value如果同时配置,优先使用value
private void collectProperties(PropertyResolver resolver, List<String> missing, List<String> nonMatching) {
String[] var4 = this.names;
int var5 = var4.length;
for(int var6 = 0; var6 < var5; ++var6) {
String name = var4[var6];
String key = this.prefix + name; //key:prefix+"."+name
if (resolver.containsProperty(key)) {
if (!this.isMatch(resolver.getProperty(key), this.havingValue)) {
nonMatching.add(name);
} //如果含有key,且key对应的值不与havingValue匹配,将name添加进nonMatching中
} else if (!this.matchIfMissing) {
missing.add(name);
} //如果不包含key,则matchingIfMissing=true,不添加进missing中,为false是添加进missing中
}
}
private boolean isMatch(String value, String requiredValue) {
if (StringUtils.hasLength(requiredValue)) {
return requiredValue.equalsIgnoreCase(value); //如果设置了havingValue,value与havingValue相等则匹配,否则不匹配
} else {
return !"false".equalsIgnoreCase(value);
} //如果没有设置havingValue,value只要不为false则匹配,value为false则不匹配
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("(");
result.append(this.prefix);
if (this.names.length == 1) {
result.append(this.names[0]);
} else {
result.append("[");
result.append(StringUtils.arrayToCommaDelimitedString(this.names));
result.append("]");
}
if (StringUtils.hasLength(this.havingValue)) {
result.append("=").append(this.havingValue);
}
result.append(")");
return result.toString();
}
}
}
**********************
示例
*******************
配置文件
application.yml
person:
enabled: true
name: 瓜田李下
age: 20
student:
name: 瓜田李下2
age: 20
*******************
pojo 层
Person
@Data
@Component
@ConditionalOnProperty(prefix = "person",value = {"enabled"},havingValue = "true")
@ConfigurationProperties("person")
public class Person {
private String name;
private Integer age;
}
Student
@Data
@Component
@ConfigurationProperties(prefix = "student")
@ConditionalOnProperty(prefix = "student",value = "enabled",matchIfMissing = true)
public class Student {
private String name;
private Integer age;
}
*******************
controller 层
HelloController
@RestController
public class HelloController {
@Resource
private Person person;
@Resource
private Student student;
@RequestMapping("/hello")
public String hello(){
System.out.println(person);
System.out.println(student);
return "success";
}
}
**********************
使用测试
localhost:8080/hello
2020-07-06 18:27:20.222 INFO 19064 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-07-06 18:27:20.228 INFO 19064 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms
Person(name=瓜田李下, age=20)
Student(name=瓜田李下2, age=20)
本文地址:https://blog.csdn.net/weixin_43931625/article/details/107140919
推荐阅读
-
Hibernate注解说明
-
Spring SpringMVC SpringBoot SpringCloud 注解整理大全
-
使用SpringBoot注解方式处理事务回滚实现
-
SpringBoot 之 @Transaction注解的类级别和方法级别的区别
-
SpringBoot @ControllerAdvice注解全局异常处理
-
每天一个SpringBoot注解之@Qualifier
-
每天一个SpringBoot注解之@Configuration
-
SpringBoot @ConfigurationProperties注解松散绑定错误
-
SpringBoot配置类注解【@PropertySource和@ConfigurationProperties】
-
SpringBoot 配置高级 ConfigurationProperties注解 宽松绑定/松散绑定 常用计量单位绑定 数据校验