[springboot源码分析]-Conditional

https://www.baeldung.com/spring-conditional-annotations

Condition元数据

1 org.springframework.context.annotation.Conditional

1.1@Conditional定义

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
	Class<? extends Condition>[] value();
}

2 org.springframework.context.annotation.Condition

2.1 Condition接口定义

@FunctionalInterface
public interface Condition {
	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

2.2 Condition类图

[springboot源码分析]-Conditional_第1张图片

2.2.1 ProfileCondition
class ProfileCondition implements Condition {

	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
		if (attrs != null) {
			for (Object value : attrs.get("value")) {
				if (context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value))) {
					return true;
				}
			}
			return false;
		}
		return true;
	}
}
2.2.2 自定义Condition
class Java8Condition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return JavaVersion.getJavaVersion().equals(JavaVersion.EIGHT);
    }
}


3.SpringBootCondition

3.1. SpringBootCondition类图

在这里插入图片描述

3.1.1 OnBeanCondition 执行图-- 粗

[springboot源码分析]-Conditional_第2张图片

3.1.2 自定义SpringBootCondition
class Java8OrJava9 extends AnyNestedCondition {
    
    Java8OrJava9() {
        super(ConfigurationPhase.REGISTER_BEAN);
    }
    
    @Conditional(Java8Condition.class)
    static class Java8 { }
    
    @Conditional(Java9Condition.class)
    static class Java9 { }

}

3.2 org.springframework.boot.autoconfigure.condition.ConditonOnXXX

[springboot源码分析]-Conditional_第3张图片



4. @ConditionalOnClass(SomeService.class)执行之旅

  @AutoConfiguration
  public class MyAutoConfiguration {
 
  	@Configuration(proxyBeanMethods = false)
  	@ConditionalOnClass(SomeService.class)
  	public static class SomeServiceConfiguration {
  	}
  }

4.1 注解元数据

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {
	Class<?>[] value() default {};
	String[] name() default {};
}

ConditionalOnBean.name=userService

4.2 执行逻辑线路

springApplication.run(args)
--prepareContext()
----load(context,sources)
------createBeanDefinitionLoader(context,sources):: return BeanDefinitionLoader // 1

//1
BeanDefinitionLoader.load()
--AnnotatedBeanDefinitionReader.register(source) //2

//2
AnnotatedBeanDefinitionReader.register(source)
--registerBean()
----doRegisterBean()
-----abd = new AnnotatedGenericBeanDefinition(beanClass);//3
----ConditionEvaluator.conditionEvaluator.shouldSkip(abd.getMetadata())//4

//4.ConditionEvaluator.shouldSkip()

4.2.1 ConditionEvaluator.shouldSkip()

class ConditionEvaluator {
	public boolean shouldSkip(AnnotatedTypeMetadata metadata) {
		return shouldSkip(metadata, null);
	}

	public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
		//判断是否存在Conditional类型注解
		if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
			return false;
		}

		//若phase 为空,则根据metadata类型设置phase --- 略..
		List<Condition> conditions = new ArrayList<>();
		//1. 获取所有的 conditionClasses
		for (String[] conditionClasses : getConditionClasses(metadata)) { 
			for (String conditionClass : conditionClasses) {
				//2 BeanUtils.instantiateClass(conditionClass); 实例化所有的condition
				Condition condition = getCondition(conditionClass, this.context.getClassLoader());
				conditions.add(condition);
			}
		}
		
		AnnotationAwareOrderComparator.sort(conditions); //排序

		for (Condition condition : conditions) {
			ConfigurationPhase requiredPhase = null;
			if (condition instanceof ConfigurationCondition) {
				requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
			}

			//3. condition.matches:: OnClassCondition.mathes
			if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
				return true;
			}
		}

		return false;
	}

	//1
	private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) {
		MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);
		Object values = (attributes != null ? attributes.get("value") : null); //OnClassCondition.class
		return (List<String[]>) (values != null ? values : Collections.emptyList());
	}
}

4.2.2 OnClassCondition.matches()



public abstract class SpringBootCondition implements Condition {

	@Override
	public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		String classOrMethodName = getClassOrMethodName(metadata);  //SomeServiceConfiguration
		ConditionOutcome outcome = getMatchOutcome(context, metadata); //子类实现;;1
		logOutcome(classOrMethodName, outcome);
		recordEvaluation(context, classOrMethodName, outcome);
		return outcome.isMatch();
	}


}


//1
class OnClassCondition extends FilteringSpringBootCondition {
	
	@Override
	public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
		ClassLoader classLoader = context.getClassLoader();
		ConditionMessage matchMessage = ConditionMessage.empty();
		List<String> onClasses = getCandidates(metadata, ConditionalOnClass.class); //1.1 SomeService.class

		@ConditionalOnClass处理逻辑
		if (onClasses != null) {
			List<String> missing = filter(onClasses, ClassNameFilter.MISSING, classLoader);
			//如果存在missing; 则noMatch
			if (!missing.isEmpty()) {
				return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class)
					.didNotFind("required class", "required classes")
					.items(Style.QUOTE, missing));
			}

			//否则 返回found
			matchMessage = matchMessage.andCondition(ConditionalOnClass.class)
				.found("required class", "required classes")
				.items(Style.QUOTE, filter(onClasses, ClassNameFilter.PRESENT, classLoader));
		}

		//@ConditionalOnMissingClass 处理逻辑
		List<String> onMissingClasses = getCandidates(metadata, ConditionalOnMissingClass.class);
		if (onMissingClasses != null) {
			List<String> present = filter(onMissingClasses, ClassNameFilter.PRESENT, classLoader);
			if (!present.isEmpty()) {
				return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnMissingClass.class)
					.found("unwanted class", "unwanted classes")
					.items(Style.QUOTE, present));
			}
			matchMessage = matchMessage.andCondition(ConditionalOnMissingClass.class)
				.didNotFind("unwanted class", "unwanted classes")
				.items(Style.QUOTE, filter(onMissingClasses, ClassNameFilter.MISSING, classLoader));
		}
		return ConditionOutcome.match(matchMessage); //返回
	}

	//1.1
	private List<String> getCandidates(AnnotatedTypeMetadata metadata, Class<?> annotationType) {
		MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(annotationType.getName(), true);
		if (attributes == null) {
			return null;
		}
		List<String> candidates = new ArrayList<>();
		addAll(candidates, attributes.get("value"));
		addAll(candidates, attributes.get("name"));
		return candidates;
	}

}

你可能感兴趣的:(spring,boot,spring)