Mybatis-Spring扫描路径有重叠导致Invalid bound statement(not found)问题

背景

近日,某个系统的测试环境mybatis总是报Invalid bound statement(not found)异常,导致tomcat容器无法启动。异常信息如下:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.management.dao.IssueDao.countByCid
        at org.apache.ibatis.binding.MapperMethod$SqlCommand.(MapperMethod.java:227)
        at org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:49)
        at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65)
        at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58)
        at com.sun.proxy.$Proxy126.countByCid(Unknown Source)
        at com.xxx.management.service.issue.IssueService.countByCid(IssueService.java:81)
        at com.xxx.management.service.issue.IssueService$$FastClassBySpringCGLIB$$be57e1e9.invoke()
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

QA同学开始以为是develop分支有代码改动导致,切到master分支重新部署,还是出现一样的问题,可是诡异的是相同的代码其实在2天前已经上线了,线上表现一切正常。于是开发同学(我)开始介入排查问题。

注意:两个环境的云主机配置,OS版本,JDK版本,tomcat版本完全一致。

问题定位

首先,我尝试本机复现,发现无论是develop分支还是master分支在本机都不会出现异常,甚至直接去测试环境scp war包到本地启动都无法复现。这就比较抓瞎了,于是只能根据错误日志开始假设排除。

假设1:mybatis interface 和 xml 映射代码错误

异常信息非常直观,就是mybatis查找不到 com.xxx.management.dao.IssueDao.countByCid 这个statement了,第一反应检查mybaits dao相关代码。

由于系统使用的是interface + xml的映射方式,所以先检查 xml 文件的namespace,没问题;再检查