• [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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2 org.springframework.context.annotation.Condition

    2.1 Condition接口定义

    @FunctionalInterface
    public interface Condition {
    	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
    }
    
    • 1
    • 2
    • 3
    • 4

    2.2 Condition类图

    在这里插入图片描述

    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;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    2.2.2 自定义Condition
    class Java8Condition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return JavaVersion.getJavaVersion().equals(JavaVersion.EIGHT);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6


    3.SpringBootCondition

    3.1. SpringBootCondition类图

    在这里插入图片描述

    3.1.1 OnBeanCondition 执行图-- 粗

    在这里插入图片描述

    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 { }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

    在这里插入图片描述



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

      @AutoConfiguration
      public class MyAutoConfiguration {
     
      	@Configuration(proxyBeanMethods = false)
      	@ConditionalOnClass(SomeService.class)
      	public static class SomeServiceConfiguration {
      	}
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4.1 注解元数据

    @Target({ ElementType.TYPE, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Conditional(OnClassCondition.class)
    public @interface ConditionalOnClass {
    	Class<?>[] value() default {};
    	String[] name() default {};
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    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());
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    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;
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
  • 相关阅读:
    使用pushd高效的切换目录
    利用python进行视频下载并界面播放快速下载素材
    快速排序Rapidly Sort
    c++11 多线程支持 (std::shared_future)
    elmentui表格修改可点击排序元素
    18_Nginx_rewrite阶段_rewrite模块
    ElasticSearch架构介绍及原理解析
    基地树洞 | 自动化小系列之番外篇
    vue3.0 构建后管 test development production 环境 以及路由跳转正常点击刷新出现cannot get
    计算机网络概述
  • 原文地址:https://blog.csdn.net/it_freshman/article/details/134014949