最近在开发的时候遇到一个问题。
我的controller中使用 @Autowired 引入service,如下:
@Slf4j
@RestController
@RequestMapping("/business")
public class BusinessController {
@Autowired
private MyService myService;
@GetMapping(value = "/myBusiness")
public BaseResponse<List<BusinessVo>> getMyBusiness(@RequestParam(value = "name") String name){
return customerService.getMyBusiness(name, UserUtils.getId());
}
}
//接口
public interface MyService {
BaseResponse<List<BusinessVo>> getMyBusiness(String name, Long id);
}
//实现类
@Slf4j
@Service
public class MyServiceImpl implements CustomerOrderService {
@Autowired
private BusinessFeign businessFeign;
public BaseResponse<List<BusinessVo>> getMyBusiness(String name, Long id){
//这里远程调用其他服务的代码
}
}
运行成功之后,访问接口,出现500错误。
后端:
然后我发现。我的BusinessController 的myService的实现类居然是:com.baomidou.mybatisplus.core.override.MybatisMapperProxy@5fc23d0
这肯定是不对的。这里的myService的对象不应该是mybaties的反射对象。应该是MyServiceImpl 才对。这种只有在映射Mapper.xml的dao时才会用这个。
我猜测这种原因是配置mapper的路径时,把mapper文件的路径扩大化了。导致使用了mybaties的反射实现,但是由于有找到对应的mapper.xml。所以程序抛出匹配异常。
所以我去找了项目配置mapper路径的地方:
@SpringBootApplication
@EnableDiscoveryClient
@ServletComponentScan
@EnableAsync
@EnableFeignClients(basePackages = {"com.zhong.test.centre.*"})
@MapperScan(basePackages = { "com.zhong.test.centre" })
public class ServerApp {
public static void main( String[] args ){
SpringApplication.run(ServerApp.class, args);
}
}
从 @MapperScan(basePackages = { "com.zhong.test.centre" })可以看出,这个mapper扫描配置将整个项目所有的文件都包括进去了(com.zhong.test.centre 是所有包的上层路径),这导致了项目在获取myservice的实现类时,使用了mybaties的反射实现(其中的逻辑我没有研究,可能会很复杂)。
解决办法:
1. 如果项目没有使用数据库,可以将@MapperScan(basePackages = { "com.zhong.test.centre" })删除。
2. 将路径缩小到我们Mapper文件具体在路径。例如:@MapperScan(basePackages = { "com.zhong.test.centre.dao.mapper" })