在@Configuration中使用通用Mapper会出现无法初始化的问题

本文探讨了在SpringBoot项目中使用通用Mapper时遇到的一个初始化问题,详细分析了问题产生的原因并给出了具体的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通用mapper

通用mapper是mybatis的扩展,它提供了一系列的通用方法,避免了冗余的xml编写和公共增删改查的重复劳动。它极大的简化了单表的增删改查,并可以随意的按照自己的需要选择通用方法,还可以很方便的开发自己的通用方法。


本人曾使用spring整合通用mapper一直未出现问题,后来项目升级为spring boot,在整合通用mapper时出现了一个问题,我也曾在github上询问(issues)作者,但作者也未提供好的解决方案。报错如下(截取了一段):

Caused by: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseSelectProvider.dynamicSQL).  Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77) ~[mybatis-spring-1.3.1.jar:1.3.1]
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446) ~[mybatis-spring-1.3.1.jar:1.3.1]
    at com.sun.proxy.$Proxy81.selectList(Unknown Source) ~[?:?]
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:230) ~[mybatis-spring-1.3.1.jar:1.3.1]
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:137) ~[mybatis-3.4.4.jar:3.4.4]
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:75) ~[mybatis-3.4.4.jar:3.4.4]
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59) ~[mybatis-3.4.4.jar:3.4.4]
    at com.sun.proxy.$Proxy82.selectAll(Unknown Source) ~[?:?]

Caused by: org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseSelectProvider.dynamicSQL).  Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider
    at org.apache.ibatis.builder.annotation.ProviderSqlSource.createSqlSource(ProviderSqlSource.java:103) ~[mybatis-3.4.4.jar:3.4.4]
    at org.apache.ibatis.builder.annotation.ProviderSqlSource.getBoundSql(ProviderSqlSource.java:73) ~[mybatis-3.4.4.jar:3.4.4]
    at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:292) ~[mybatis-3.4.4.jar:3.4.4]
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81) ~[mybatis-3.4.4.jar:3.4.4]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148) ~[mybatis-3.4.4.jar:3.4.4]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141) ~[mybatis-3.4.4.jar:3.4.4]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_111]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_111]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_111]

作者说这个问题是由于通用mapper没有初始化引起的,我查阅了关于spring boot中Configuration和AutoConfiguration加载顺序的资料,得出问题原因:spring boot中Configuration的加载在AutoConfiguration之前。
but, 为什么mybatis的starter初始化没有问题?
github上的一篇文章解答了这个问题(但我目前没在spring官网找到该描述的出处,如您找到了,请告知,谢谢。)
Configuration和AutoConfiguration加载顺序
我翻看了作者实现starter的源码,发现作者是使用 @PostConstruct 完成通用mapper的初始化的,所以在 Configuration 之后才会初始化,这就引发了以上的错误。
弄明白了问题所在,那该怎么解决呢?


弄明白原因了,其实问题就解决了,我们只要让通用mapper的AutoConfiguration在Configuration之前加载就可以了,但我们没办法在使用作者提供的starter,需要自己来实现。我将实现后的代码放到了github


后来我有翻看了作者的另一个关于mybatis开源项目PageHelper,发现它的starter也是通过 @PostConstruct 实现,所以它也会有上面描述的问题,我把它的starter也修改了,放到了github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值