[springboot源码分析]

编程入门 行业动态 更新时间:2024-10-23 01:47:28

[springboot<a href=https://www.elefans.com/category/jswz/34/1770099.html style=源码分析]"/>

[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源码分析]

本文发布于:2023-12-03 20:39:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1657405.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:源码   springboot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!