必须同时添加@indexed注解和spring-context-indexer依赖才能启用编译时索引优化:前者标记可索引组件,后者在编译期生成meta-inf/spring.components文件,使spring启动时跳过类路径扫描而直接读取索引。

给需要被 Spring 扫描的类加上 @Indexed,同时在项目中引入 spring-context-indexer 依赖,就能让编译时生成 META-INF/spring.components 索引文件,启动时跳过类路径扫描,直接读取索引——这是最核心的优化逻辑。
必须配齐两个条件
单独加注解或只加依赖都不起作用:
- 所有要纳入索引的组件类(
@Component、@Service、@Controller等)必须显式标注@Indexed,或者使用 Spring 自带的、已内置@Indexed的注解(如@Component本身从 5.0 起就自带该元注解) -
pom.xml中需声明spring-context-indexer依赖,并设为<optional>true</optional>,避免它被传递到下游模块
正确引入 indexer 依赖
Maven 配置示例(推荐用与 Spring Framework 版本匹配的版本,如 5.3.x 或 6.1.x):
<dependency><groupid>org.springframework</groupid><artifactid>spring-context-indexer</artifactid><optional>true</optional></dependency>
Gradle 用户可写:annotationProcessor 'org.springframework:spring-context-indexer'(注意不是 compileOnly 或 implementation)
引入后,每次 mvn compile 或 IDE 构建,都会自动生成 target/classes/META-INF/spring.components 文件,内容形如:com.example.service.UserService=org.springframework.stereotype.Service
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
扫描行为自动切换
Spring 启动时会自动检测 classpath 下是否存在有效的 spring.components 文件:
- 存在且格式合法 → 使用
CandidateComponentsIndexLoader加载索引,跳过实际的类路径扫描 - 不存在或损坏 → 回退到传统全量扫描模式,不影响功能,只是没提速
无需修改 @ComponentScan 或 XML 配置,原有扫描范围保持不变,只是底层实现从“运行时遍历”变为“编译时预登记 + 启动时查表”。
适合哪些场景?哪些要避开?
适用:
- 模块稳定、组件数量多(>200 个带注解的类)的中大型项目
- 频繁构建部署、对启动时间敏感的微服务(如 Kubernetes 环境下 Pod 快速扩缩容)
- 多模块工程中,将通用组件打成独立 jar 包并启用索引,能显著减少主应用扫描负担
慎用:
- 开发阶段频繁增删组件类 → 索引不会自动更新,需手动 rebuild 才生效
- 使用反射动态加载、非标准路径注册 Bean 的场景 → 索引无法覆盖这类逻辑
- 混合了大量第三方 jar(未启用 indexer)→ 只有你自己模块的索引有效,其他仍需扫描










