Spring Boot 无自动检测未使用 Bean 功能,但可通过四步识别:一查注册(--debug、/actuator/beans、getBeanDefinitionNames);二查静态引用(IDE Find Usages);三查运行时获取(Actuator、BeanPostProcessor、AOP埋点);四查XML幽灵Bean(lazy-init、版本兼容、迁移@Configuration)。

Spring Boot 中没有内置的“自动检测未使用 Bean”功能,因为“未使用”本身是业务语义——容器无法判断一个 Bean 是否被代码逻辑真正调用过,只能判断它是否被注册、是否被注入、是否被显式获取过。但我们可以结合多种手段,**识别出高概率未被使用的 Bean**,尤其适用于清理冗余配置、优化启动耗时或排查 XML/JavaConfig 中遗留的无效声明。
一、先确认 Bean 是否被注册进容器
这是前提。如果一个 Bean 根本没注册,自然谈不上“未使用”。常用方式:
- 启动时加参数 --debug(如
java -jar app.jar --debug),Spring Boot 会输出自动配置报告,同时列出所有已加载的 Bean 及其来源(ConditionEvaluationReport); - 启用 Actuator 的 /actuator/beans 端点(需配置
management.endpoints.web.exposure.include=beans),访问后可直观看到所有 Bean 名称、类型、作用域、依赖关系和定义来源(如@Configuration类或 XML 文件); - 在启动类中获取
ApplicationContext,调用getBeanDefinitionNames()打印全部名称,快速核对目标 Bean 是否在列表中。
二、检查 Bean 是否被任何地方注入或引用
静态分析比运行时更可靠,尤其适合发现“注册了但从不被 @Autowired 的 Bean”:
- 在 IntelliJ IDEA 中,右键点击某个 Bean 类名 → 选择 Find Usages(或按
Alt+F7),查看是否有@Autowired、@Resource、构造器参数、方法参数等位置引用它; - 若该 Bean 是接口类型,还需检查其实现类是否被注入(例如
MyService接口有多个实现,只有一部分被@Qualifier指定); - 注意:匿名内部类、Lambda 表达式、反射调用(如
Class.forName(...).getDeclaredMethod(...).invoke(...))可能逃逸静态扫描,需人工确认。
三、借助工具识别“注册但从未被获取”的 Bean
运行时可观测性更强,能捕获动态行为:
- 使用 Spring Boot DevTools 的
/actuator/beans页面(非纯 JSON,带搜索和折叠),观察每个 Bean 的dependencies字段是否为空,且无其他 Bean 在injectionPoints中指向它; - 自定义 BeanPostProcessor 或 SmartInitializingSingleton,在所有单例初始化完成后遍历
applicationContext.getBeanDefinitionNames(),逐个调用applicationContext.containsBean(beanName)并记录;再结合日志埋点(如 AOP 拦截所有getBean()调用),对比哪些 Bean 始终未被取用; - 第三方工具如 Spring Boot Admin 或 Arthas 可在运行时执行 OGNL 表达式,实时查询
context.getBeanDefinitionCount()和实际活跃引用数。
四、特别关注 XML 配置中的“幽灵 Bean”
XML 方式更容易遗留无主 Bean,因其脱离 Java 编译检查:
- 检查
<bean id="xxx" class="...">是否设置了lazy-init="true"且从未被其他 Bean 依赖 —— 这类 Bean 启动时不实例化,也难被发现; - 用 Maven 命令
mvn dependency:tree -Dincludes=org.springframework确认是否引入了旧版 Spring(如 4.x)的 XML 解析器,避免因版本兼容问题导致某些<bean>被静默忽略; - 将 XML 配置逐步迁移至
@Configuration类后,利用 IDE 的“未使用符号”提示(灰色标识)直接定位废弃 Bean。


















