You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中@ConditionalOn*注解机制及相关问题解析

Spring Boot自动配置:打包与运行时无依赖兼容机制

背景

我基于spring-boot-starter-web搭建了一个极简Spring Boot项目,类路径里包含spring-boot-autoconfigure包——这个包里预定义了CassandraAutoConfiguration这类覆盖各种技术栈的自动配置类。但我的项目没加Cassandra相关依赖,运行时也不会创建对应的Bean,这里想搞清楚背后的两个核心机制。


1. JAR打包阶段:怎么避免编译失败?

你的猜测完全正确,核心是用可选依赖处理编译期依赖:

  • 官方在构建spring-boot-autoconfigure时,会把Cassandra、Redis这类第三方组件的依赖标记为「可选」(Maven里是<optional>true</optional>,Gradle里用compileOnly或optional配置)。
  • 编译的时候,这些可选依赖会被拉取到本地,保证CassandraAutoConfiguration这类自动配置类能正常编译(毕竟代码里要引用Cassandra的类);但打包成最终JAR时,这些依赖不会被包含进去,也不会传递给依赖spring-boot-autoconfigure的下游项目(比如你的web项目)。
  • 这种设计让一个spring-boot-autoconfigure包就能覆盖所有技术栈的自动配置,同时不会强迫用户引入一堆没用的依赖。

2. 运行时阶段:缺依赖为啥能加载自动配置类不报错?

靠条件注解+类加载机制的组合实现:

  • 首先,CassandraAutoConfiguration类上标注了@ConditionalOnClass(CassandraTemplate.class)这类条件注解。Spring启动扫描到这个类时,会先检查类路径里有没有CassandraTemplate这类Cassandra核心类——如果没有,直接跳过这个类的Bean创建流程,根本不会去执行类里的代码。
  • 其次,Java的类加载是延迟加载的:CassandraAutoConfiguration类本身被加载时,只会加载它自己的字节码,不会主动去加载它引用的Cassandra相关类。只有当Spring要执行这个类的Bean创建方法时,才会尝试加载那些依赖类,但因为条件注解已经把这个流程拦截了,所以永远不会触发这个加载操作,自然不会出现ClassNotFoundException。
  • 简单说:Spring只是把CassandraAutoConfiguration的类文件读进JVM,但不会去初始化它或者调用它的方法,所以不会碰那些缺失的依赖类。

内容的提问来源于stack exchange,提问作者Žeka Koževin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:12:38