@Resource 按字段名查找的坑 Spring Boot 启动失败BeanNotOfRequiredTypeExceptionnacosGracefulShutdownDelegate连环报错分析一、错误现象应用启动时直接失败控制台打印大量异常堆栈主要包括两类错误1. 核心错误导致启动失败org.springframework.beans.factory.BeanCreationException: Error creating bean with name assessmentIndicatorSyncJob: Injection of resource dependencies failed Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name assessmentIndicatorCalcServiceImpl: Injection of resource dependencies failed Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named tenantFrameworkService is expected to be of type ...TenantCommonApi but was actually of type ...TenantFrameworkServiceImpl2. 次生错误Context 关闭时反复出现org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name nacosGracefulShutdownDelegate: Singleton bean creation not allowed while singletons of this factory are in destruction该错误重复出现5~6 次随后应用退出。二、错误根因分析2.1 定位问题代码ServicepublicclassAssessmentIndicatorCalcServiceImplimplementsAssessmentIndicatorCalcService{ResourceprivateTenantCommonApitenantFrameworkService;// ← 问题在这里// ...}2.2Resource注入机制Resource的查找顺序是先按 bean name字段名匹配匹配不到再按类型匹配因为字段名叫tenantFrameworkServiceSpring 就去容器中找名为tenantFrameworkService的 Bean。2.3 容器中实际存在什么容器中确实有一个 Bean 叫tenantFrameworkService但它来自yudao-spring-boot-starter-biz-tenant模块// TenantFrameworkServiceImpl.javaRequiredArgsConstructorpublicclassTenantFrameworkServiceImplimplementsTenantFrameworkService{// 它实现的是 TenantFrameworkService 接口privatefinalTenantCommonApitenantApi;// 内部包装了 TenantCommonApi}而代码中声明的类型是// TenantCommonApi.java — 这是一个 Feign 客户端接口FeignClient(nameRpcConstants.SYSTEM_NAME)publicinterfaceTenantCommonApi{// RPC 远程调用接口CommonResultTenantRespDTOgetTenant(RequestParam(id)Longid);}2.4 类型关系类/接口类型说明TenantCommonApiFeign 客户端接口RPC 远程调用通过 HTTP 调用 system-serverTenantFrameworkService本地服务接口定义本地租户服务方法TenantFrameworkServiceImpl本地服务实现类实现TenantFrameworkService内部包装了TenantCommonApi并加了 Guava 缓存TenantFrameworkServiceImpl不实现TenantCommonApi它们是两个完全不同的类型体系。2.5 结论字段名声明的类型容器中实际匹配到的 Bean结果tenantFrameworkServiceTenantCommonApiTenantFrameworkServiceImpl类型TenantFrameworkService❌BeanNotOfRequiredTypeException三、Nacos 报错为什么出现3.1 事件链① BeanNotOfRequiredTypeException (tenantFrameworkService 类型不匹配) ↓ ② ApplicationContext.refresh() 失败 → 调用 doClose() 清理 ↓ ③ doClose() 发布 ContextClosedEvent ↓ ④ Nacos 的 nacosGracefulShutdownDelegate 监听器收到事件 ↓ ⑤ 该监听器尝试 getBean() → 但 BeanFactory 已在销毁状态 ↓ ⑥ BeanCreationNotAllowedException: Singleton bean creation not allowed...3.2 为什么重复 5~6 次看堆栈中间NamedContextFactory.destroy() ← Spring Cloud LoadBalancer 的子容器销毁 → AbstractApplicationContext.close() → doClose() 发布 ContextClosedEvent → nacosGracefulShutdownDelegate 再次尝试 getBean()NamedContextFactorySpring Cloud LoadBalancer会为每个服务创建独立的子 ApplicationContext。销毁时每个子 Context关闭都会发布ContextClosedEventNacos 监听器又注册在每个子 Context 中所以触发多次。3.3 错误性质错误性质原因BeanNotOfRequiredTypeException根因Resource字段名导致按名称匹配到错误的 BeanBeanCreationNotAllowedException次生启动失败后关闭 Context 时Nacos 在销毁阶段试图 getBeanNacos 线程池/HttpClient 销毁日志正常清理容器销毁时的正常善后动作四、解决方案4.1 修复方法将字段名改为不与任何 Bean 名冲突让Resource退化为按类型匹配// 修改前ResourceprivateTenantCommonApitenantFrameworkService;// ❌ 按名称匹配到 TenantFrameworkServiceImpl// 修改后ResourceprivateTenantCommonApitenantCommonApi;// ✅ 按类型匹配到 TenantCommonApi 的 Feign Bean同时删除无用的 import// 删除这行从未使用importcn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;4.2 修复后的调用// 使用处同步修改CommonResultTenantRespDTOcommonResulttenantCommonApi.getTenant(TenantContextHolder.getTenantId());4.3 原理说明字段名改为tenantCommonApi后Spring 找不到名为tenantCommonApi的 Bean于是退回到按类型匹配正确匹配到 Feign 框架自动创建的TenantCommonApi代理 Bean注入成功。五、教训与最佳实践5.1ResourcevsAutowired注解默认匹配方式注意事项Resource先按 bean name再按 type字段名会影响注入结果Autowired先按 type再按 name字段名一般不影响注入除非有多个同类型 Bean5.2 字段命名建议字段名不要与其他已知的 Bean 名相同否则Resource会按名称匹配字段名应该反映声明的类型而不是想要的功能例如TenantCommonApi类型的字段就叫tenantCommonApi而不是tenantFrameworkService5.3 遇到类似错误时的排查思路找到最底层的Caused by而非最上面的报错看BeanNotOfRequiredTypeException中的三个关键信息Bean 名tenantFrameworkService期望类型TenantCommonApi实际类型TenantFrameworkServiceImpl检查字段声明是否与 Bean 名冲突上层的 Nacos 报错通常是次生灾害忽略即可六、参考Spring Resource AnnotationSpring Cloud Nacos Graceful ShutdownDefaultSingletonBeanRegistry 源码

相关新闻

最新新闻

SerenityOS 命令行选项解析指南:getopt 与 getopt_long 用法、返回值与底层实现

SerenityOS 命令行选项解析指南:getopt 与 getopt_long 用法、返回值与底层实现

SerenityOS 命令行选项解析指南:getopt 与 getopt_long 用法、返回值与底层实现 【免费下载链接】serenity The Serenity Operating System 🐞 项目地址: https://gitcode.com/GitHub_Trending/se/serenity 导读 本文以 getopt(3) 手册 为核心&a…

2026/10/3 16:42:15
轻量服务器还是ECS?大促云服务器选购与避坑实战指南

轻量服务器还是ECS?大促云服务器选购与避坑实战指南

每年大促节点,群里永远有人在问同一个问题:“38元的轻量服务器到底怎么抢?为什么我每次点进去都是已售罄?68元直购和99元的ECS我到底选哪个?”作为一个常年帮团队和自己采购云服务器的老用户,我太清楚这种纠…

2026/10/3 16:42:30
为 AI 代理的 Review 动作编写 Cedar 审批门控策略:review-agent-governance 策略编写实战指南

为 AI 代理的 Review 动作编写 Cedar 审批门控策略:review-agent-governance 策略编写实战指南

为 AI 代理的 Review 动作编写 Cedar 审批门控策略:review-agent-governance 策略编写实战指南 【免费下载链接】agents Multi-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity 项目地址:…

2026/10/3 16:42:22
PaddleOCR 手写数学公式识别算法 CAN 实战指南:Counting-Aware Network 训练、评估与推理部署

PaddleOCR 手写数学公式识别算法 CAN 实战指南:Counting-Aware Network 训练、评估与推理部署

PaddleOCR 手写数学公式识别算法 CAN 实战指南:Counting-Aware Network 训练、评估与推理部署 【免费下载链接】PaddleOCR Turn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between i…

2026/10/3 7:41:27
Spring源码解析:构造器注入的类型转换与候选匹配机制

Spring源码解析:构造器注入的类型转换与候选匹配机制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 16:42:24
openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由

openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由

openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由 【免费下载链接】openai-agents-python A lightweight, powerful framework for multi-agent workflows 项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-pyth…

2026/10/3 16:42:28

日新闻

周新闻

月新闻