@mapperscan扫描包混有@service
问题描述
@mapperscan注解配置的一般是dao或者mapper的扫描包,一般用于数据库操作,里面类的一般都是接口,如果在dao层有其他接口,比如说@service等就会报错
解决办法一
把service包移走,方法可行
解决办法二
不使用@mapperscan,在每个dao或者mapper里面加上注解@mapper,方法可行
解决办法三
使用自定义注解,在mybatis的注解比较完善的情况下,就不用自己搞多少
创建注解@mymapperscan
里面的属性全部抄袭@mapperscan
mapperscannerregistrar换成自己的
@retention(retentionpolicy.runtime) @target(elementtype.type) @documented @import(mymapperscannerregistrar.class) @repeatable(mapperscans.class) public @interface mapperscan { string[] value() default {}; string[] basepackages() default {}; class<?>[] basepackageclasses() default {}; class<? extends beannamegenerator> namegenerator() default beannamegenerator.class; class<? extends annotation> annotationclass() default annotation.class; class<?> markerinterface() default class.class; string sqlsessiontemplateref() default ""; string sqlsessionfactoryref() default ""; class<? extends mapperfactorybean> factorybean() default mapperfactorybean.class; string lazyinitialization() default ""; }
mymapperscannerregistrar扫描注册器
这个类和mybatis的一模一样,唯一的不同就是myclasspathmapperscanner是自己的扫描
public class mymapperscannerregistrar extends mapperscannerregistrar { private resourceloader resourceloader; /** * {@inheritdoc} */ @override public void registerbeandefinitions(annotationmetadata importingclassmetadata, beandefinitionregistry registry) { annotationattributes annoattrs = annotationattributes.frommap(importingclassmetadata.getannotationattributes(mapperscan.class.getname())); //这个是自己的 classpathmapperscanner scanner = new myclasspathmapperscanner(registry); // this check is needed in spring 3.1 if (resourceloader != null) { scanner.setresourceloader(resourceloader); } class<? extends annotation> annotationclass = annoattrs.getclass("annotationclass"); if (!annotation.class.equals(annotationclass)) { scanner.setannotationclass(annotationclass); } class<?> markerinterface = annoattrs.getclass("markerinterface"); if (!class.class.equals(markerinterface)) { scanner.setmarkerinterface(markerinterface); } class<? extends beannamegenerator> generatorclass = annoattrs.getclass("namegenerator"); if (!beannamegenerator.class.equals(generatorclass)) { scanner.setbeannamegenerator(beanutils.instantiateclass(generatorclass)); } class<? extends mapperfactorybean> mapperfactorybeanclass = annoattrs.getclass("factorybean"); if (!mapperfactorybean.class.equals(mapperfactorybeanclass)) { scanner.setmapperfactorybean(beanutils.instantiateclass(mapperfactorybeanclass)); } scanner.setsqlsessiontemplatebeanname(annoattrs.getstring("sqlsessiontemplateref")); scanner.setsqlsessionfactorybeanname(annoattrs.getstring("sqlsessionfactoryref")); list<string> basepackages = new arraylist<string>(); for (string pkg : annoattrs.getstringarray("value")) { if (stringutils.hastext(pkg)) { basepackages.add(pkg); } } for (string pkg : annoattrs.getstringarray("basepackages")) { if (stringutils.hastext(pkg)) { basepackages.add(pkg); } } for (class<?> clazz : annoattrs.getclassarray("basepackageclasses")) { basepackages.add(classutils.getpackagename(clazz)); } scanner.registerfilters(); scanner.doscan(stringutils.tostringarray(basepackages)); } /** * {@inheritdoc} */ @override public void setresourceloader(resourceloader resourceloader) { this.resourceloader = resourceloader; } }
myclasspathmapperscanner
自己的扫描类基本也是mybatis的,就是在判断上面改动了一点点
public class myclasspathmapperscanner extends classpathmapperscanner { public myclasspathmapperscanner(beandefinitionregistry registry) { super(registry); } @override protected boolean iscandidatecomponent(annotatedbeandefinition beandefinition) { boolean flag = super.iscandidatecomponent(beandefinition); //包名带有mapper的才会被mybatis代理 boolean mapper = beandefinition.getbeanclassname().contains("mapper"); return flag && mapper; } }
现在只需要用自己的扫描注解即可,用法和mybatis的一模一样
解决办法四
这个是针对第三点的,作者使用第三点的时候mybatis版本为3.4.6
mybatis-spring版本为1.3.2,spring版本为5.x
当mybatis版本为3.5.2的mybatis-spring版本为2.0.2的时候
mapperscannerregistrar类扫描的方式发生了一点点变化,
还需要改写mapperscannerconfigurer类,其他的不变
完毕!
解决办法五
@mapperscan注解使用markerinterface或者annotationclass参数限制扫描的接口
@mapperscan包扫描的坑
在使用通用mapper执行查询时
由于不太注意顺手就导了spring的包:
import org.mybatis.spring.annotation.mapperscan;
结果就异常:
tk.mybatis.mapper.provider.base.baseselectprovider:xxxx
找了半天才发现是包的问题
应该导mybatis的mapperscan而不是spring中的包,正确的包名:
import tk.mybatis.spring.annotation.mapperscan;
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。