前言
昨天在項(xiàng)目中使用代碼生成器生成了各層面的代碼,但是由于未知的原因一直無法調(diào)用。經(jīng)過多方查找后才發(fā)現(xiàn)是@MapperScan注解的問題,由于這個(gè)藏得比較隱蔽,所以在此記錄一下。
問題描述
在接口完成后調(diào)用接口,發(fā)現(xiàn)無法調(diào)用接口,顯示錯(cuò)誤是
ERROR 1552 --- [nio-8081-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.mydemo.service.xxxxxx] with root cause
大致的意思是綁定錯(cuò)誤,無法達(dá)到映射的意思。無法找到Service包下面的xxxxService實(shí)現(xiàn)類。
排查過程
從百度上看,一般可能是mapper綁定失敗所致,所以先從排查mapper有關(guān)的類和接口甚至文件開始。
- ?檢查xml文件所在package名稱是否和Mapper interface所在的包名一一對(duì)應(yīng);
- ?檢查xml的namespace是否和xml文件的package名稱一一對(duì)應(yīng);
- ?檢查方法名稱是否對(duì)應(yīng);
- ?檢查配置文件里的mapper路徑是否正確
但是這里排查了很多遍,都沒有發(fā)現(xiàn)相關(guān)的問題。同事給了我一個(gè)方法,測(cè)試接口是否確實(shí)被注入了。
@Autowired
private ApplicationContext applicationContext;
@GetMapping("test")
public void test(){
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String beanName : beanNames) {
Object bean = applicationContext.getBean(beanName);
if (bean instanceof Mapper) {
// 處理Mapper的Bean實(shí)例
System.out.println(beanName + " is a Mapper bean.");
}
}
}
運(yùn)行后發(fā)現(xiàn),mapper確實(shí)注入了。
所以有可能是Service接口和實(shí)現(xiàn)類的問題,按照這個(gè)思路進(jìn)行排查。
然后排查到啟動(dòng)類上面,當(dāng)時(shí)的啟動(dòng)類是這么寫的
@MapperScan(value = {
"com.jsb.iot.common",
"com.jsb.iot.stopcar.parking_lot",
"com.jsb.iot.stopcar.order"
})
@SpringBootApplication
public class StopCarApplication {
public static void main(String[] args) {
SpringApplication.run(StopCarApplication.class, args);
}
}
試著給類名后面的包名加上dao以縮小掃描范圍。
@MapperScan(value = {
"com.jsb.iot.common",
"com.jsb.iot.stopcar.parking_lot.dao",
"com.jsb.iot.stopcar.order.dao"
})
@SpringBootApplication
public class StopCarApplication {
public static void main(String[] args) {
SpringApplication.run(StopCarApplication.class, args);
}
}
發(fā)送請(qǐng)求測(cè)試,結(jié)果測(cè)試成功。搜查后發(fā)現(xiàn)原因
原因
@Mapper
org.apache.ibatis.annotations.Mapper;
作用:給該注解下面的接口在編譯時(shí)生成對(duì)應(yīng)的動(dòng)態(tài)代理類并且注入到Spring容器中。
@MapperScan
org.mybatis.spring.annotation.MapperScan;
作用:在啟動(dòng)類上配置,配置的是持久層接口的包的路徑。編譯后會(huì)把路徑下所有的接口都生成動(dòng)態(tài)代理類
包下面的所有接口都會(huì)實(shí)現(xiàn)代理類,這就意味著在之前的寫法中,除了impl類被注入了Spring容器中之外,還注入了一個(gè)Service的實(shí)現(xiàn)類,于是乎在Controller層調(diào)用Service時(shí),并沒有真正獲取被注入的impl類,所以無法調(diào)用mapper接口。這種情況只有運(yùn)行時(shí)才會(huì)報(bào)錯(cuò)。
總結(jié)
@MapperScan指定范圍下的所有接口,是所有接口,不論是Mapper接口、還是Service接口、或者是其它什么接口,只要接口是在@MapperScan指定的范圍內(nèi),Mybatis都會(huì)對(duì)該接口進(jìn)行對(duì)應(yīng)的代理實(shí)現(xiàn)(并將代理實(shí)現(xiàn)類注冊(cè)進(jìn)容器中)。所以在使用@MapperScan時(shí),一定要注意指定的范圍不能過大。
@Mapper和@MapperScan注解以及共存
在排查問題時(shí),偶然遇到@Mapper和@MapperScan注解的共存情況問題,現(xiàn)在把結(jié)果附加上去。
- 只使用@Mapper注解,不使用@MapperScan注解。會(huì)掃描@Mapper注解所在接口,生成動(dòng)態(tài)代理類,注入到Spring容器中。
- 只使用@MapperScan注解,不使用@Mapper注解。會(huì)掃描@MapperScan注解配置的包下面的接口生成動(dòng)態(tài)代理類,注入到Spring容器中。
- @Mapper、@MapperScan注解都使用,使用@Mapper的接口,如果在@MapperScan注解中有配置包路徑,那么可以正常使用。
- @Mapper、@MapperScan注解都使用,使用@Mapper的接口,如果在@MapperScan注解中沒有配置包路徑,那么會(huì)報(bào)錯(cuò),解決辦法,就是在@MapperScan注解中配置正確路徑下的包即可。
?參考
?2021120101_@Mapper和@MapperScan注解以及共存_mapperscan和mapper注解-CSDN博客目錄1、@Mapper、@MapperScan注解2、報(bào)錯(cuò)使用場(chǎng)景1、@Mapper、@MapperScan注解@Mapper注解:使用:直接在接口類上使用,包是:org.apache.ibatis.annotations.Mapper作用:為有此注解的接口生成動(dòng)態(tài)代理類,并且注入到spring容器中。@MapperScan注解:使用:在啟動(dòng)類上配置,配置的是持久層接口的包路徑,標(biāo)注批量生成此包下的接口的動(dòng)態(tài)代理類,并且注入到容器中。2、報(bào)錯(cuò)使用場(chǎng)景問題描述:使用_mapperscan和mapper注解https://blog.csdn.net/m0_48983233/article/details/121648122
?@MapperScan與@Mapper_@mapperscan和@mapper-CSDN博客@MapperScan與@Mapper@MapperScan與@Mapper背景說明@MapperScan與@Mapper的作用通過@Mapper讓Mybatis對(duì)接口提供代理實(shí)現(xiàn)通過@MapperScan讓Mybatis對(duì)接口提供代理實(shí)現(xiàn)背景說明我們?cè)诰帉憁apper時(shí),只需要編寫接口而不需要對(duì)其實(shí)現(xiàn),由Mybatis框架對(duì)接口提供對(duì)應(yīng)的代理實(shí)現(xiàn)類(,并將代理實(shí)現(xiàn)類注冊(cè)進(jìn)容器中)。但是Mybatis是怎么知道需要對(duì)哪些接口進(jìn)行代理實(shí)現(xiàn)呢,就是通過@MapperScan與@Mappe_@mapperscan和@mapperhttps://blog.csdn.net/justry_deng/article/details/124227444文章來源:http://www.zghlxwxcb.cn/news/detail-786759.html
?SpringBoot中Service實(shí)現(xiàn)類添加@Service卻任然無法注入的問題 - 簡(jiǎn)書最近一直在研究Spring Boot。從GitHub上下載了一個(gè)my-Blog源碼,一邊看,一邊自己嘗試去實(shí)現(xiàn),結(jié)果掉在坑了,研究了近一周才爬出來,特地來這博客園記錄下來,一...https://www.jianshu.com/p/b72a1ffb3672文章來源地址http://www.zghlxwxcb.cn/news/detail-786759.html
到了這里,關(guān)于SpringBoot項(xiàng)目中添加了@Service然而無法注入Service接口的問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!