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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值