SpringBoot系列:用配置影响Bean加载 @ConditionalOnProperty

时间:2025-04-04 07:08:29
package org.springframework.boot.autoconfigure.condition; ... @Order(Ordered.HIGHEST_PRECEDENCE + 40) class OnPropertyCondition extends SpringBootCondition { @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { // 通过获类原始数据上的ConditionalOnProperty注解的参数值 List<AnnotationAttributes> allAnnotationAttributes = annotationAttributesFromMultiValueMap( metadata.getAllAnnotationAttributes(ConditionalOnProperty.class.getName())); List<ConditionMessage> noMatch = new ArrayList<>(); List<ConditionMessage> match = new ArrayList<>(); for (AnnotationAttributes annotationAttributes : allAnnotationAttributes) { // 通过属性值,逐一判断配置信息中的信息是否满足 , () 能获取到所有的配置信息 ConditionOutcome outcome = determineOutcome(annotationAttributes, context.getEnvironment()); (outcome.isMatch() ? match : noMatch).add(outcome.getConditionMessage()); } if (!noMatch.isEmpty()) { return ConditionOutcome.noMatch(ConditionMessage.of(noMatch)); } return ConditionOutcome.match(ConditionMessage.of(match)); } private List<AnnotationAttributes> annotationAttributesFromMultiValueMap( MultiValueMap<String, Object> multiValueMap) { ... return annotationAttributes; } private ConditionOutcome determineOutcome(AnnotationAttributes annotationAttributes, PropertyResolver resolver) { Spec spec = new 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, spec) .didNotFind("property", "properties").items(Style.QUOTE, missingProperties)); } if (!nonMatchingProperties.isEmpty()) { return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, spec) .found("different value in property", "different value in properties") .items(Style.QUOTE, nonMatchingProperties)); } return ConditionOutcome .match(ConditionMessage.forCondition(ConditionalOnProperty.class, 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) { ... } private String[] getNames(Map<String, Object> annotationAttributes) { ... } private void collectProperties(PropertyResolver resolver, List<String> missing, List<String> nonMatching) { for (String name : this.names) { String key = this.prefix + name; if (resolver.containsProperty(key)) { // havingValue 默认为 "" if (!isMatch(resolver.getProperty(key), this.havingValue)) { nonMatching.add(name); } } else { if (!this.matchIfMissing) { missing.add(name); } } } } private boolean isMatch(String value, String requiredValue) { if (StringUtils.hasLength(requiredValue)) { return requiredValue.equalsIgnoreCase(value); } // havingValue 默认为 "" ,因此只要对应的属性不为false,在注解中没填havingValue的情况下,都是会match上conditon,即都会被加载 return !"false".equalsIgnoreCase(value); } @Override public String toString() { ... } } }