栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ConditionalOnClass实现原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ConditionalOnClass实现原理

Spring Boot实现了很多有⽤的条件注⼊,其中的实现让⼈感到困惑,因为如果类不存在的话,加载就ConditionalOnClass会抛出错误,其实Spring Boot使⽤的字节码技术来实现这⼀点的。

实现原理
Spring在加载类之前,会提前使⽤字节码技术来读取这个类(并没有使⽤ClassLoader),然后解析⾥⾯的ConditionalOnClass,再在classpath下找到对应的类,如果找到就注⼊,否则就不注⼊
最终是否满条件的逻辑
匹配的⽅法:SpringBootCondition#matches(ConditionContext, AnnotatedTypeMetadata)
其中AnnotatedTypeMetadata就会通过字节码技术解析得到的注解信息,可以通过断点的⽅式,可以跟踪注解信息是如何从字节码解析得到的

@Override
public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    String classOrMethodName = getClassOrMethodName(metadata);
    try {
        ConditionOutcome outcome = getMatchOutcome(context, metadata);
        logOutcome(classOrMethodName, outcome);
        recordEvaluation(context, classOrMethodName, outcome);
        return outcome.isMatch();
    }
    catch (NoClassDefFoundError ex) {
        throw new IllegalStateException("Could not evaluate condition on " + classOrMethodName + " due to "
                + ex.getMessage() + " not found. Make sure your own configuration does not rely on "
                + "that class. This can also happen if you are "
                + "@ComponentScanning a springframework package (e.g. if you "
                + "put a @ComponentScan in the default package by mistake)", ex);
    }
    catch (RuntimeException ex) {
        throw new IllegalStateException("Error processing condition on " + getName(metadata), ex);
    }
}

关键路径
通过跟踪Spring解析流程,可以得到以下字节码解析类信息的路径如下。
 

public static void main(String[] args) throws Exception {
    FileSystemResource resource = new FileSystemResource("/projects/test/target/classes/com/test/User.class");
    //元数据解析器⼯⼚
    CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
    //元数据解析器
    MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
    //解析出来的类元数据
    ClassMetadata classMetadata = metadataReader.getClassMetadata();
    System.out.println(classMetadata);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873822.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号