源码分析]"/>
[springboot源码分析]
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类图
2.2.1 ProfileCondition
class ProfileCondition implements Condition {@Overridepublic 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 {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return JavaVersion.getJavaVersion().equals(JavaVersion.EIGHT);}
}
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 { }}
3.2 org.springframework.boot.autoconfigure.condition.ConditonOnXXX
4. @ConditionalOnClass(SomeService.class)执行之旅
@AutoConfigurationpublic 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. 获取所有的 conditionClassesfor (String[] conditionClasses : getConditionClasses(metadata)) { for (String conditionClass : conditionClasses) {//2 BeanUtils.instantiateClass(conditionClass); 实例化所有的conditionCondition 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.mathesif ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {return true;}}return false;}//1private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) {MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);Object values = (attributes != null ? attributes.get("value") : null); //OnClassCondition.classreturn (List<String[]>) (values != null ? values : Collections.emptyList());}
}
4.2.2 OnClassCondition.matches()
public abstract class SpringBootCondition implements Condition {@Overridepublic final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {String classOrMethodName = getClassOrMethodName(metadata); //SomeServiceConfigurationConditionOutcome outcome = getMatchOutcome(context, metadata); //子类实现;;1logOutcome(classOrMethodName, outcome);recordEvaluation(context, classOrMethodName, outcome);return outcome.isMatch();}}//1
class OnClassCondition extends FilteringSpringBootCondition {@Overridepublic 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; 则noMatchif (!missing.isEmpty()) {return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class).didNotFind("required class", "required classes").items(Style.QUOTE, missing));}//否则 返回foundmatchMessage = 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.1private 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;}}
更多推荐
[springboot源码分析]
发布评论