(1)问题形容
自己设置了一个 MyBatis 阻拦器,用于阻拦查询语句。阻拦器的签名为:
@Component@Intercepts( @Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} ))public class SelectSqlInterceptor implements Interceptor{…}
执行后抛出异常,完整异常日志如下:
java.lang.IllegalStateException: Failed to execute CommandLineRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:779) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE] at com.fsti.cc.core.ds.DSApplication.main(DSApplication.java:30) [classes/:na]Caused by: org.apache.ibatis.exceptions.PersistenceException:### Error opening session. Cause: org.apache.ibatis.plugin.PluginException: Could not find method on class org.apache.ibatis.javassist.bytecode.analysis.Executor named query. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.javassist.bytecode.analysis.Executor.query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)### Cause: org.apache.ibatis.plugin.PluginException: Could not find method on class org.apache.ibatis.javassist.bytecode.analysis.Executor named query. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.javassist.bytecode.analysis.Executor.query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler) at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:100) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession(DefaultSqlSessionFactory.java:57) ~[mybatis-3.5.6.jar:3.5.6] at org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:105) ~[mybatis-spring-2.0.6.jar:2.0.6] at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:424) ~[mybatis-spring-2.0.6.jar:2.0.6] at com.sun.proxy.$Proxy57.selectList(Unknown Source) ~[na:na] at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) ~[mybatis-spring-2.0.6.jar:2.0.6] at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:152) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85) ~[mybatis-3.5.6.jar:3.5.6] at com.sun.proxy.$Proxy58.selectAll(Unknown Source) ~[na:na] at com.fsti.cc.core.ds.DSApplication.run(DSApplication.java:35) [classes/:na] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE] ... 5 common frames omittedCaused by: org.apache.ibatis.plugin.PluginException: Could not find method on class org.apache.ibatis.javassist.bytecode.analysis.Executor named query. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.javassist.bytecode.analysis.Executor.query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler) at org.apache.ibatis.plugin.Plugin.getSignatureMap(Plugin.java:83) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.plugin.Plugin.wrap(Plugin.java:44) ~[mybatis-3.5.6.jar:3.5.6] at com.fsti.cc.core.ds.interceptor.SelectSqlInterceptor.plugin(SelectSqlInterceptor.java:55) ~[classes/:na] at org.apache.ibatis.plugin.InterceptorChain.pluginAll(InterceptorChain.java:31) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.session.Configuration.newExecutor(Configuration.java:681) ~[mybatis-3.5.6.jar:3.5.6] at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:96) ~[mybatis-3.5.6.jar:3.5.6] ... 17 common frames omittedCaused by: java.lang.NoSuchMethodException: org.apache.ibatis.javassist.bytecode.analysis.Executor.query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler) at java.lang.Class.getMethod(Class.java:1786) ~[na:1.8.0_181] at org.apache.ibatis.plugin.Plugin.getSignatureMap(Plugin.java:80) ~[mybatis-3.5.6.jar:3.5.6] ... 22 common frames omitted
(2)起因分析
org.apache.ibatis.javassist.bytecode.analysis.Executor 类中并没有 query 方法,所以抛错。
(3)问题处理
实际上 MyBatis 依赖中包含两个同名的 Executor 类,自己设置的阻拦器签名需要的类是org.apache.ibatis.executor.Executor。我们进入该类源代码,可以看到的确有相应的 query 方法: