Springboot @ConditionOnXXX是如何实现的

在这里插入图片描述

前言

问题

主要是发现了一个问题,在看springboot 源码的时候。
在这里插入图片描述
这种飘红的代码就没有这个类,但项目依然可以启动起来。为什么?

先看下@ConditionalOnClass

  1. @ConditionalOnClass这个注解有一个基础注解@Conditional,还可以看到一个OnClassCondition.class,这个属性是一个数组。
    在这里插入图片描述
  2. Conditional这个接口,SpringBootCondition就实现了这个接口来对Contional注解进行处理

在这里插入图片描述

  1. 下面是这几个核心类的关系
    在这里插入图片描述

Spring如何判断一个类是否加载呢

  1. 先给出一个加载链路

org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])
org.springframework.boot.SpringApplication#run(java.lang.String...)
org.springframework.boot.SpringApplication#prepareContext
org.springframework.boot.SpringApplication#load
    org.springframework.boot.BeanDefinitionLoader#load()
    org.springframework.boot.BeanDefinitionLoader#load(java.lang.Object)
    org.springframework.boot.BeanDefinitionLoader#load(java.lang.Class<?>)
        org.springframework.context.annotation.AnnotatedBeanDefinitionReader#register
        org.springframework.context.annotation.AnnotatedBeanDefinitionReader#registerBean(java.lang.Class<?>)
        org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
            org.springframework.context.annotation.ConditionEvaluator#shouldSkip(org.springframework.core.type.AnnotatedTypeMetadata)
            org.springframework.context.annotation.ConditionEvaluator#shouldSkip(org.springframework.core.type.AnnotatedTypeMetadata, org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase)
                org.springframework.context.annotation.Condition#matches
                org.springframework.boot.autoconfigure.condition.SpringBootCondition#matches(org.springframework.context.annotation.ConditionContext, org.springframework.core.type.AnnotatedTypeMetadata)
                org.springframework.boot.autoconfigure.condition.SpringBootCondition#getMatchOutcome
                org.springframework.boot.autoconfigure.condition.OnClassCondition#getMatchOutcome
                    org.springframework.boot.autoconfigure.condition.FilteringSpringBootCondition#filter
                        org.springframework.boot.autoconfigure.condition.FilteringSpringBootCondition.ClassNameFilter#matches
                        org.springframework.boot.autoconfigure.condition.FilteringSpringBootCondition.ClassNameFilter#isPresent

核心流程

  1. ConditionEvaluator#shouldSkip这个方法主要是判断类是否要跳过加载。

在这里插入图片描述

  1. SpringBootCondition#matches是判断符合条件

在这里插入图片描述
在这里插入图片描述
3. 看下SpringBootCondition#getMatchOutcome

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

看到这里我们就可以知道ConditionalOnClass注解里的类属性是通过类加载器和forName的方法判断类路径上是否有该类,如果类路径上有该类则加载成功,也就是能够成功匹配,成功匹配后SpringBoot就会把ConditionalOnClass注解标记的类加入到容器中。

这里可以看出,没有加载成功的spring已经把异常给catch住了,只是没有往上抛出。

参考文章

猜你喜欢

转载自blog.csdn.net/qq_37362891/article/details/119773338