想象你是一家叫 Spring Boot 的餐厅后厨新来的学徒。你惊讶地发现,主厨只需在点菜单上勾选几样“菜品”(引入依赖),后厨的“智能备菜系统”就自动把对应的食材、调料、餐具全部准备妥当——切好的肉丝、调好的酱汁、预热好的烤箱,统统不用你亲自动手。你忍不住问:这系统怎么知道我要做宫保鸡丁?它怎么判断食材够不够?我要是想换成麻辣口味怎么办?别急,这篇文章就是带你把后厨的“智能备菜系统”拆开看个明白。你会发现,所谓“魔法”背后,其实是一套精心设计的判断逻辑、一份藏在角落的清单和几条清晰的优先级规则。看完之后,你不仅能看懂魔法,还能亲手设计一套属于自己的“备菜系统”。
对 Java 从业者而言,读透自动配置原理意味着你能快速定位启动异常、顺手写出企业级 Starter 组件、在技术面试中讲清“魔法”背后的真实逻辑,这是从“会用框架”迈向“懂框架”的关键一步。
可视化演示
动态演示Spring Boot自动配的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
Spring Boot自动配:Enab EnableAutoConfi Conditional条件注解 核心机制可视化 Spring Boot自动配整体架构与关键组件
自动配置初识
小明站在后厨门口,看着主厨在点菜单上勾了几下,十五分钟后整桌菜的材料就齐了。他忍不住问:“系统怎么知道今晚需要备哪些菜?”主厨指着墙上的一行字说:“菜单上写了什么,备菜系统就准备什么——这叫自动配置。”
所谓自动配置,指的是 Spring Boot 扫描项目 classpath 上已有的第三方依赖 jar 包,根据这些依赖自动创建并注册所需的 Bean,从而省去传统 Spring 开发中手写 XML 或 Java 配置类的繁琐过程。你引入 spring-boot-starter-web,它就自动配好 DispatcherServlet 和 Tomcat;你引入 spring-boot-starter-data-jpa,它就自动配好 DataSource 和 EntityManagerFactory。这些“默认动作”构成了自动配置的核心思想:约定优于配置,让开发者只关注业务代码。
自动配置带来的最大转变是从“命令式配置”走向“声明式运行”。过去你用 XML 声明每一个 Bean、每一次依赖注入;现在你只需要在类路径里放一个 jar,系统自动帮你把“该有的都配好”。但“自动”不是“盲目”,它背后有一套严谨的选择逻辑。这套逻辑可以形式化地表达为:从候选配置集合中,筛选出满足匹配条件的那些配置。
如果把自动配置比作备菜系统,那么 B_{final} 就是最终端到客人面前的菜,C_{candidate} 是墙上那份可能上百道菜的总菜单,而 matched(b) 就是后厨“这道菜有没有食材、有没有人点”的判断过程。所谓魔法,不过是一场高效的筛选。
- 最终Bean集合
B_{final}表示最终注册进 Spring 容器的所有 Bean,相当于后厨最终端上桌的菜品。 - 候选配置集合
C_{candidate}是所有自动配置类的集合,好比后厨备菜清单上列出的全部候选菜。 - 匹配函数
matched(b)是判断某一配置是否应该生效的函数,好比后厨检查“这道菜的材料够不够”。
启动总开关
小明在系统的控制面板上看到一个醒目的大按钮,旁边写着“自动配置总开关”。他按下按钮,整个后厨的备菜流水线轰然启动。这颗按钮的名字,叫 @EnableAutoConfiguration。
@EnableAutoConfiguration 是自动配置的入口注解,它通常与 @SpringBootApplication 复合使用。这个注解本身并不直接做配置,而是通过 @Import 机制引入一个“向导类”—— AutoConfigurationImportSelector。这个向导类负责从 META-INF/spring.factories(更准确地说,是 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)中读取所有候选配置类名,然后逐个筛选。
@Import 是 Spring 框架提供的一种导入机制,可以将普通类、配置类或 ImportSelector 实现类导入容器。AutoConfigurationImportSelector 实现了 ImportSelector 接口,它的 selectImports 方法返回一个字符串数组,数组里是待注册的配置类全限定名。这个设计把“读哪些配置”的决定权完全交给了选择器,主流程只负责执行。
这颗总开关的妙处在于,它把“启动什么”和“怎么装配”彻底解耦。后厨按下按钮只是开启流程,具体备哪道菜由清单和条件决定。你可以通过 exclude 临时“撤掉某道菜”,也可以依赖后面的条件关卡做精细控制。这正是 Spring Boot 高度可扩展性的起点。
exclude 属性显式排除的类。- 读取候选清单
scanFactories(classpath)表示遍历运行时类路径,找到所有 jar 包中标记“此为自动配置”的文件。 - 排除指定项
excludeSet是用户通过@EnableAutoConfiguration(exclude = ...)手动排除的类集合,相当于“明确不做这道菜”。 - 集合差运算
\setminus表示从候选中剔除排除项,结果才是真正参与评估的候选集。
条件装配
接下来,小明发现备菜流水线上有一个个“判定关卡”。每个依赖包要经过一道门,门上的规则各不相同:有的要求“必须有鸡肉”,有的要求“没有现成的宫保酱”。只有通过关卡的食材才会被送入装配区。这些关卡,对应着 Spring Boot 里庞大的 @Conditional 条件注解家族。
条件装配是自动配置的“决策大脑”。@ConditionalOnClass 检查指定类是否存在于 classpath 中;@ConditionalOnMissingBean 检查容器中是否不存在某个 Bean;还有 @ConditionalOnProperty、@ConditionalOnExpression、@ConditionalOnWebApplication 等等。每一个条件注解背后都有一个 Condition 接口的实现类,它的 matches 方法返回布尔值,决定配置类是否生效。
以最常用的 @ConditionalOnClass 为例,它的判据是:如果指定的类能被当前类加载器加载成功,说明依赖存在,条件通过;否则条件失败,整个配置类被跳过。这个过程发生在容器启动的极早期,因此要遵循“严谨、快速”的原则——不能启动数据库连接来做判断,只能做轻量级的类路径探测。
把条件装配想象成备菜流水线上的自动分拣机:每个食材包贴上自己的标签,分拣机根据预设规则把它分到“可用区”或“回收区”。正是因为有了这一道道关卡,自动配置才能做到“有依赖就装配、无依赖就跳过”,既不会因为缺依赖而启动失败,也不会做多余的无用功。
- 类加载探测
classExists(\text{指定类})尝试用Class.forName加载目标类,成功则返回 true。 - 分支判断整个公式是一个分段函数,条件成立走 true 分支(通过),否则走 false 分支(跳过)。
- 封装为注解这个判断逻辑被封装成
@ConditionalOnClass(name = "com.mysql.cj.jdbc.Driver")这样的声明式写法。
清单加载机制
小明很好奇:系统怎么知道总共有哪些“候选菜”?主厨领他走到仓库角落,从架子上取下一个厚厚的笔记本,封面上写着“备菜总清单—— META-INF/spring.factories”。每个依赖 jar 里都夹着一页这样的清单,把自己能提供的自动配置类登记在上面。
在 Spring Boot 2.7 之前,所有自动配置类都登记在 META-INF/spring.factories 文件中;2.7 之后新增了 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,用更简洁的行式声明替代键值对。加载这些清单的组件叫 SpringFactoriesLoader,它会在应用启动时扫描 classpath 下所有 jar 包中的清单文件,把配置类名汇总起来。
加载过程还要处理两个细节:一是排序,@AutoConfigureOrder、@AutoConfigureBefore、@AutoConfigureAfter 注解共同决定配置类的先后执行顺序;二是去重,多个 jar 可能声明同一个配置类,必须保证只加载一次。排序和去重保证了自动配置的确定性和可预测性。
这份“备菜总清单”是整个自动配置体系的索引层。它不关心某道菜具体怎么做,只负责登记“谁会做这道菜”。当你在项目的 pom 里引入一个新依赖,它的 jar 包中自带的清单就被扫描进来,候选菜谱自动多了一页。这就是为什么引入一个 starter,就能获得对应功能的全部自动装配。
- 遍历所有JAR
resource \in classpath表示遍历所有 classpath 下的 jar 包或目录。 - 读取清单行
readLines(resource, key)从文件的EnableAutoConfiguration键下读出配置类全限定名列表。 - 合并并集
\bigcup确保多个来源的配置类合并时不重复,同一类名只保留一个。
配置优先级
今天店里来了位客人,对服务员说:“宫保鸡丁不要放花生。”备菜系统收到这个特殊要求后,立刻调整了自动生成的菜品配方。小明问主厨:“如果默认配方和客人的特殊要求冲突了,听谁的?”主厨笑道:“我们有一套严格的优先级规则,特殊要求永远赢。”
Spring Boot 的配置覆盖也遵循同样的优先级逻辑。spring.datasource.url 这个配置项可能同时存在于多个来源:命令行参数、系统环境变量、application.yml 文件、默认值。Spring Boot 规定:配置来源优先级从高到低依次为命令行参数、Java 系统属性、环境变量、application.yml、默认值。
@ConfigurationProperties 注解把这些配置值批量绑定到类型安全的属性类上,让自动配置的 Bean 可以读取用户自定义值。当你显式声明一个同名 Bean 时,Spring Boot 会尊重你的声明,自动配置的 Bean 自动退让——这就是“用户优先”原则。如果什么都没配,则回退到自动配置的默认值。
这套优先级规则就像餐厅的“特需优先”制度:客人的特别嘱咐(命令行参数)永远最重要,备菜手册(配置文件)次之,最后才是通用标准(默认值)。理解了它,你就能精准地覆盖自动配置:想调端口,命令行加参数;想改连接串,写进 yml;什么都不动,就用默认值——层层递进,清晰可控。
- 最高优先级
v_{cmd}表示命令行参数--server.port=8081这样的输入,它在所有来源中优先权最高。 - 次级来源
v_{yml}表示application.yml中的配置项,当命令行未传时作为第二选择。 - 最终兜底
v_{default}是自动配置类中注解或代码里写死的默认值,保证任何情况下都有值可用。
自定义Starter
一个月后,小明已经熟练掌握了后厨的备菜系统。他开始琢磨:我能不能也开发一套“备菜模块”,让其他餐厅直接安装使用?主厨赞许地说:“这就对了,Spring Boot 里这叫自定义 Starter。”
自定义 Starter 的标准结构包含两个模块:xxx-spring-boot-starter 和 xxx-spring-boot-autoconfigure。前者是空 jar,只传递相关依赖,方便用户一句“引入依赖”就能用;后者存放自动配置类,是真正的“备菜逻辑”所在。自动配置类需要标注 @AutoConfiguration 注解,并配合 @ConditionalOnClass 等条件注解控制生效范围。
写好的配置类需要登记到 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中,每行一个类全限定名。如果需要暴露配置项,则配合 @EnableConfigurationProperties 把属性类注册进容器。这样,其他项目引入你的 starter 后,Spring Boot 启动时就会自动加载断言、装配、配置好你的组件。
自定义 Starter 好比把后厨的一套“备菜方案”封装成标准化的预制模块:既有“食材清单”(依赖),又有“做菜流程”(自动配置类),还有个“说明书”(清单登记)。使用者只需引入一个依赖,这套方案便自动融入他的项目,真正做到“开箱即用”。
- 配置模块
autoconfigure模块是核心,内含自动配置类和@ConfigurationProperties属性类。 - 依赖传递starter 模块通过 pom 依赖把 autoconfigure 和相关第三方库带给使用者。
- 文件登记在自动配置导入文件中写下配置类的全限定名,是 Stater 生效的“最后一公里”。
调试与排错
系统偶尔也会出乱子。某天,小明发现一个自动配置的 Bean 神秘消失了,程序启动时报 Field dataSource required a bean of type。主厨不慌不忙地敲入一行命令 --debug,屏幕上刷出了一份详细的“备菜评估报告”。
这份报告就是自动配置的调试利器。启动时加上 --debug 参数(或在配置中设 debug=true),Spring Boot 会输出所有自动配置类的评估结果:Positive matches 列出条件通过、成功装配的配置;Negative matches 列出条件不满足、被跳过的配置及原因;Exclusions 列出被显式排除的配置。有了这份报告,你可以精准定位“哪个条件卡住了哪个配置”。
常见故障主要有三类:一是依赖缺失,条件类在 classpath 中不存在导致跳过;二是 Bean 冲突,用户显式声明的 Bean 让自动配置的 Bean 退让;三是配置属性写错,@ConfigurationProperties 前缀或字段名对不上。调试技巧上,除了 --debug 报告,还可以用 SpringApplication 的日志级别调整、ConditionEvaluationReport 编程式获取评估结果。
调试报告就像后厨的“故障自查单”:哪道菜被取消了、为什么被取消、是谁手动改过,全都白纸黑字写清楚。遇到装配失败,先看 Negative matches 里的原因——是缺食材(依赖)?还是条件设卡?还是有人抢了这道菜(Bean 冲突)?对症下药,问题往往迎刃而解。
- 逐项评估
eval(condition_i)对第 i 个配置类执行条件匹配,输出 match/fail 结果。 - 汇总合计
\sum表示把全部配置类的评估结果汇集成一份结构化报告。 - 报告输出最终
report被渲染成启动日志中的 Positive/Negative 列表。
AI 应用场景
企业级中间件开发
阶段:模型推理服务的基础设施组件开发
解决的问题:AI 平台需要为算法团队提供统一的模型加载、特征计算等中间件。传统做法要求每个项目各自复制一份配置代码,维护成本高、版本易漂移。利用自动配置原理,将模型加载器封装为自定义 Starter,算法团队只需引入依赖,配置一个模型路径即可获得完整的推理服务初始化。
具体案例:某 AI 公司开发了 model-serving-spring-boot-starter,算法工程师在 application.yml 里写 model.path=/models/bert-base 就完成了模型加载、预热和接口暴露的全部装配,平均接入时间从 2 天降到 2 小时。
智能配置中心对接
阶段:配置管理与动态调参(特征开关、模型版本切换)
解决的问题:AI 服务的超参数、模型版本、特征开关经常需要动态调整,硬编码或单一配置文件无法满足。利用配置优先级规则,把远程配置中心的参数作为最高优先级来源,配合 @ConfigurationProperties 批量绑定,让自动配置的 Bean 随配置刷新。
具体案例:某推荐系统团队用 spring-cloud-config 管理 A/B 实验开关,运营人员在配置中心调整 “召回模型版本” 下的开关值,线上服务无需重启即在下一个请求周期生效,实验迭代周期从一周缩短到一天。
AI 模型推理框架的 Spring Boot 封装
阶段:将 Python 训练的模型集成到 Java 推理服务
解决的问题:Java 服务需要加载 ONNX、TensorFlow 等格式的模型,原生调用涉及大量样板代码。运用自定义 Starter 方法论,封装 onnx-runtime-spring-boot-starter,用 @ConditionalOnClass 判断运行时是否存在 onnxruntime 库,用 @ConditionalOnProperty 控制推理引擎的启用。
具体案例:某金融风控团队在反欺诈服务中引入封装后的 ONNX 推理 Starter,模型推理调用从手写 200 行初始化代码简化为 3 行配置,推理延时稳定在 5ms 以内,模型上线流程完全自动化。
Python 演示
class SpringFactoriesLoader: """模拟Spring Factory加载器""" def __init__(self, factory_files): self._factory_map = {} for path, content in factory_files.items(): self._factory_map[path] = content def load_factory_names(self, factory_type): names = [] seen = set() for content in self._factory_map.values(): if factory_type not in content: continue for name in content[factory_type]: if name not in seen: seen.add(name) names.append(name) return names class ConditionEvaluator: """条件评估器""" def __init__(self, classpath_jars): self.classpath_jars = set(classpath_jars) self.positive = [] self.negative = [] def has_class(self, class_name): return class_name in self.classpath_jars def evaluate(self, config_class, required_class): if self.has_class(required_class): self.positive.append(config_class) return True self.negative.append((config_class, "缺少: " + required_class)) return False def main(): factory_files = { "mysql.jar": {"EnableAutoConfiguration": ["DataSourceAutoConfiguration"]}, "redis.jar": {"EnableAutoConfiguration": ["RedisAutoConfiguration"]}, "mongo.jar": {"EnableAutoConfiguration": ["MongoAutoConfiguration"]} } loader = SpringFactoriesLoader(factory_files) candidates = loader.load_factory_names("EnableAutoConfiguration") evaluator = ConditionEvaluator( ["com.mysql.cj.jdbc.Driver", "redis.clients.jedis.Jedis"] ) rules = { "DataSourceAutoConfiguration": "com.mysql.cj.jdbc.Driver", "RedisAutoConfiguration": "redis.clients.jedis.Jedis", "MongoAutoConfiguration": "com.mongodb.client.MongoClient" } print("=== 自动配置评估报告 ===") for config in candidates: required = rules[config] matched = evaluator.evaluate(config, required) print(f"{config}: {'通过' if matched else '跳过'} (依赖={required})") print("\n启用配置:", evaluator.positive) print("跳过配置:", evaluator.negative) if __name__ == "__main__": main()
self._factory_map[path] = content用一个字典保存每个 jar 包中的“清单内容”,模拟spring.factories文件读取。load_factory_names(factory_type)模拟SpringFactoriesLoader,按类型键读取配置类名,并自动去重。evaluate(config_class, required_class)模拟@ConditionalOnClass判定,检查依赖类是否在 classpath 中。self.positive.append(...)` / `self.negative.append(...)分别记录匹配通过和未通过的配置,生成“评估报告”。
常见误区
误区Spring Boot 的自动配置太神奇了,像是框架内置的黑魔法,我只需要会加依赖就行,原理什么的用不到。
正解自动配置本质是“普通 Java 注解 + 条件判断 + 配置文件读取”的组合,不是玄学。@EnableAutoConfiguration 导入选择器,选择器读取清单,再结合 @Conditional 决定装配——每一环都可追踪、可解释。遇到启动失败、配置不生效时,不懂原理就只能靠猜;懂原理就能看负匹配报告快速定位。
为何常见:Spring Boot 的“开箱即用”体验让人误以为它替你屏蔽了一切;简历上写的越多,潜意识越不想承认自己只停留在“会用”层面。
误区只要在 pom 里加了一个 starter,它包含的所有自动配置类就一定会生效,容器里就会有一大堆 Bean。
正解每个自动配置类都带多个 @Conditional 注解,条件不满足就整体跳过。比如引入 spring-boot-starter-data-redis 后,若 classpath 中没有 Jedis 客户端,RedisAutoConfiguration 根本不会生效。自动配置是“有条件的自动”,不是“无脑的全配”。
为何常见:人们习惯把“自动”理解为“全部自动”,忽视了“按需自动”这个前提;也是因为正常运行时没人会看启动日志里的 Negative matches。
误区只要我把配置类写进 spring.factories 并放到资源目录下,Spring Boot 就一定能读到;放哪里无所谓。
正解标准位置必须严格遵循 META-INF/spring.factories(Spring Boot 2.7 之后是 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)。SpringFactoriesLoader 用固定路径去 classpath 下搜索,放错目录文件不会被扫描到,你的自动配置就永远不生效。
为何常见:Java 的类路径搜索对初学者是个黑盒,直觉上认为“只要在项目里就能找到”,忽略了框架对资源路径的强约定。
误区自动配置的 Bean 是框架给的,我要是想换掉它,只能去改 Spring Boot 源码或者用 exclude 全部禁掉。
正解正确姿势是在容器中显式声明一个自定义 Bean,@ConditionalOnMissingBean 会让自动配置的 Bean 自动退让;或用 @ConfigurationProperties 绑定自定义属性覆盖默认值;再配合配置优先级,命令行参数直接覆盖 yml 值。这些机制都提供了“顺势而为”的扩展口,不需要破环基础设施。
为何常见:看到自动配置生成一堆 Bean 以为它们是“内定的”,不知道框架特意留了 @ConditionalOnMissingBean 这样的用户优先后门。
误区`--debug` 输出的自动配置报告是出错时才看的排错工具,正常运行的项目完全用不上。
正解报告是理解项目“实际装配了什么”的最佳窗口,也是做技术方案评审、代码审查时的重要依据。日常开发中随时可以用 --debug 启动一次,检查自己的自定义配置是否真的生效、有没有意外的 Bean 冲突,还能从中学习优秀框架的装配思路。
为何常见:调试工具被天然贴上“出错才查看”的标签,人们忽略了它在“事前验证、事中理解”层面的价值。
面试题
Q1. @EnableAutoConfiguration 在 Spring Boot 中的核心作用是?
- A.开启自动配置引擎← 正确答案
- B.声明配置属性类
- C.扫描应用同级包
- D.注册Web控制器
答案:A。@EnableAutoConfiguration 是整个自动配置的“总开关”,它通过 @Import 引入 AutoConfigurationImportSelector,从而启动候选配置类的加载和筛选流程。B 是 @ConfigurationProperties 的职责,C 是 @ComponentScan 的职责,D 是 @Controller 相关注解的职责,三者都不是自动配置的入口。
Q2. @ConditionalOnClass 注解的“类路径检测”指的是什么?
- A.扫描当前类路径下的注解文件
- B.判断指定类能否被ClassLoader加载← 正确答案
- C.将类文件编译为字节码格式
- D.检查类对象是否被容器接管
答案:B。@ConditionalOnClass 的核心逻辑是用类加载器尝试加载指定类,加载成功则条件成立。它不做文件扫描、不做编译、也不检查容器状态,只做轻量级的 Class.forName 探测。A 是组件扫描概念,C 是编译期行为,D 是容器管理概念。
Q3. spring.factories 配置文件必须放置在哪个目录下?
- A.项目资源的根目录下
- B.META-INF目录之下← 正确答案
- C.源码与资源同级处
- D.任意自定义目录中
答案:B。SpringFactoriesLoader 按固定路径 META-INF/spring.factories 在 classpath 下搜索,这是框架约定的标准位置。放错地方不会被扫描到,自动配置就不会生效。A、C、D 都不是 Spring Boot 约定的配置文件位置。
Q4. 想用自定义Bean覆盖自动配置的Bean,最推荐的做法是什么?
- A.修改框架配置源码实现
- B.删除Starter依赖重新导入
- C.定义Bean并配合条件注解← 正确答案
- D.在XML中编写全部配置
答案:C。自动配置类通常标注 @ConditionalOnMissingBean,你只需在容器中声明自定义 Bean,自动配置就会自动退让,这是官方推荐的覆盖方式。改源码不可维护,删依赖则丢失功能,XML 配置与自动配置的扩展理念背道而驰。
Q5. AutoConfigurationImportSelector 类的主要职责是?
- A.读取清单筛选配置← 正确答案
- B.编译条件类指令
- C.管理Bean生命周期
- D.转换配置为JSON
答案:A。AutoConfigurationImportSelector 实现 ImportSelector 接口,在 selectImports 方法中调用 SpringFactoriesLoader 读取所有候选配置类名,并交给后续的条件评估流程。B 是 JIT/编译器概念,C 是 BeanFactory/生命周期处理器职责,D 是序列化工具职责。
Q6. 自动配置与传统XML配置相比最核心的优势是?
- A.代码性能提升十倍
- B.根据依赖自动装配← 正确答案
- C.完全取代逻辑编程
- D.消除所有程序错误
答案:B。自动配置的价值在于“按需自动装配”——classpath 有 MySQL 驱动就配数据源,有 Jedis 就配 Redis 客户端,省去手写 XML 的样板代码。它不承诺性能翻倍、不取代业务编程,更不可能消除所有错误。
Q7. 条件评估报告中 "Negative matches" 表示什么?
- A.已启动的自动配置项
- B.条件不满足被跳过的项← 正确答案
- C.检测到的所有程序异常
- D.正在运行的守护线程
答案:B。Negative matches 列出所有条件评估未通过、被跳过的自动配置类及原因,是调试“配置不生效”问题的第一手资料。A 对应 Positive matches,C 是异常堆栈,D 是 JVM 线程概念,都与条件评估报告无关。
Q8. 自定义 Starter 工程通常包含哪两个模块?
- A.autoconfigure模块← 正确答案
- B.starter入口依赖← 正确答案
- C.独立Web服务器
- D.数据库客户端驱动
答案:AB。标准 Starter 结构是 autoconfigure 模块(存放配置逻辑)加 starter 模块(传递依赖、对接使用者)。Web 服务器如 Tomcat 是运行时容器,不属于 Starter 组成部分;数据库驱动可能作为依赖被引入,但并不是 Starter 的标准组成模块。
Q9. 多个自动配置类的执行顺序由什么决定?
- A.配置文件声明的顺序
- B.@AutoConfigureBefore注解← 正确答案
- C.@AutoConfigureAfter注解← 正确答案
- D.类名首字母的字典序
答案:BC。Spring Boot 通过 @AutoConfigureBefore 和 @AutoConfigureAfter 声明配置类之间的先后关系,结合 @AutoConfigureOrder 做全局排序。配置文件声明顺序只影响普通 Bean 定义,字典序也不是官方排序依据,所以 B、C 正确。
Q10. 下列哪些情况会导致自动配置的 Bean 不生效?
- A.相关依赖未加入类路径← 正确答案
- B.显式声明了相同Bean← 正确答案
- C.使用--debug参数启动
- D.注解排除该配置类← 正确答案
答案:ABD。缺依赖会让 @ConditionalOnClass 失败而跳过;显式声明同类 Bean 触发 @ConditionalOnMissingBean 退让;exclude 属性直接移除候选配置。而 --debug 只是开启详细日志,不会影响 Bean 装配结果,因此选 A、B、D。