@Resouce引发的错误

还原现场

优化前的代码:

java 复制代码
// package cn.com.servermanager.controller;

@RestController
public class ProcessingController {

    @Autowired
    private ProcessingServiceImpl processingService;

    @PostMapping("/xxxx")
    public Result getProcessingServer() {
        return processingService.getProcessingServer();
    }
}
java 复制代码
// package cn.com.servermanager.service;

@Service
public class ProcessingServiceImpl {

    @Autowired
    private ProcessingFeignService processingFeignService;

    public Result getProcessingServer() {
        return processingFeignService.getProcessingServer();
    }
}
java 复制代码
// package cn.com.servermanager.feignclient;

@ConditionalOnClass({Feign.class, Hystrix.class})
@Service
@FeignClient(
    name = GlobalConstants.MANAGER,
    path = "/xxxx",
    fallbackFactory = ProcessingFallbackFactory.class,
    contextId = "Processing")
public interface ProcessingFeignService {

    @PostMapping("/")
    Result getProcessingServer();
}

优化前,ProcessingServiceImpl只是对ProcessingFeignService做了简单的包装。优化后,删掉ProcessingServiceImpl,ProcessingController使用@Resource直接注入ProcessingFeignService

java 复制代码
// package cn.com.servermanager.controller;

@RestController
public class ProcessingController {

    @Resource
    ProcessingFeignService processingFeignService;

    @PostMapping("/xxxx")
    public Result getProcessingServer() {
        return processingFeignService.getProcessingServer();
    }
}

代码优化后程序正常启动,但是调用接口时报错:

java 复制代码
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.com.servermanager.feignclient.ProcessingFeignService.getProcessingServer
	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.<init>(MybatisMapperMethod.java:51)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.lambda$cachedInvoker$0(MybatisMapperProxy.java:111)
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
	at com.baomidou.mybatisplus.core.toolkit.CollectionUtils.computeIfAbsent(CollectionUtils.java:117)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.cachedInvoker(MybatisMapperProxy.java:98)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at com.sun.proxy.$Proxy216.getGeoProcessingServerResp(Unknown Source)
	at cn.com.servermanager.controller.ProcessingController.getProcessingServer(ProcessingController.java:37)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)

处理

一个feignClient接口为何报ibatis相关的错误,难道是ibatis做了她不该做的事情?查看入口类的注解,果然ProcessingFeignService在MapperScan的扫描范围内

java 复制代码
@EnableFeignClients(basePackages = {"cn.com.common.feignclient", "cn.com.servermanager.feignclient"})
@SpringBootApplication()
@MapperScan("cn.com.servermanager.*")
@ComponentScan({"cn.com.servermanager", "cn.com.common"})
@ServletComponentScan
public class ServerManagerApplication {
    public static void main(String[] args) {
        // 无关代码省略      
    }

}

抛开细节简单说,通过查看@MapperScan和@EnableFeignClients的源码知晓:

1,被MapperScan扫描的接口会以非限定名作为beanName装配到spring的容器中,即spring容器中存在名为ProcessingFeignService的bean

2,被EnableFeignClients扫描的接口会以全限定名作为beanName并以contextId+"FeignClient"作为Alias装配到spring容器中,即spring容器中存在名为cn.com.servermanager.feignclient.ProcessingFeignService的bean,它的别名是ProcessingFeignClient

因此优化后的代码才会报ibatis的错误,因为通过@Resource注入的bean是被mybatis实例化的。

此时,摆在我们面前的解决方案有多种:

java 复制代码
// 原始代码
@Resource 
ProcessingFeignService processingFeignService;

// 方案一:修改变量名
@Resource 
ProcessingFeignService processingService; 

// 方案二:指定bean名称
@Resource(name = "ProcessingFeignClient")
ProcessingFeignService processingFeignService;

// 方案三:改用@Autowired
@Autowired
ProcessingFeignService processingFeignService;

方案一能生效的原因:@Resouce默认按照名称匹配bean,如果没找到则会按照类型匹配。

方案二能生效的原因:ProcessingFeignService在spring容器中的bean别名是ProcessingFeignClient。

方案三能生效的原因:@Autowired默认按照类型匹配bean。

问题解决了,但是还有两个需要优化的地方:

1,@MapperScan扫描的包范围尽量做到精确,避免粒度大装配太多无意义的bean。

2,@Service注解使用在ProcessingFeignService接口上是无效的。

相关推荐
阳光是sunny6 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
灯澜忆梦6 小时前
GO_并发编程---定时器
开发语言·后端·golang
阳光是sunny6 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
皮皮林5517 小时前
开源实力派,给本地 AI 装上深度调研能力,一张 3090 跑到 95.7 分!
后端
努力的小雨7 小时前
把 Windows 桌面图标做成一个会自己运转的小世界
后端
武子康8 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
腾渊信息科技公司9 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
IT_陈寒10 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端
段一凡-华北理工大学10 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
码事漫谈11 小时前
1999年的电商前夜和2026年的AI前夜 历史押韵但从不重复
后端