@autoWired Injected objects that do not match expectations. The result was a problem with the Mybatis scan
@Mapper
This annotation is the default annotation class scanned when Mybatis is automatically configured
MybatisAutoConfiguration.AutoConfiguredMapperScannerRegistrar#registerBeanDefinitions
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
logger.debug("Searching for mappers annotated with @Mapper");
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
try {
if(this.resourceLoader ! = null) { scanner.setResourceLoader(this.resourceLoader); } List<String> packages = AutoConfigurationPackages.get(this.beanFactory);if (logger.isDebugEnabled()) {
for (String pkg : packages) {
logger.debug("Using auto-configuration base package '{}'", pkg); }} / / scan @ Mapper annotate the scanner setAnnotationClass (Mapper. Class); scanner.registerFilters(); scanner.doScan(StringUtils.toStringArray(packages)); } catch (IllegalStateException ex) { logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.", ex); }}Copy the code
@MapperScan
Set scan properties for manual scanning. You can set scan packages, scan notes and other information
MapperScannerRegistrar#registerBeanDefinitions
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
ClassPathMapperScanner scanner = new ClassPathMapperScanner(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));
}
Copy the code
As you can see from the code above, everything that is scanned by @mapperscan is scanned (injected into MapperFactoryBean).
The problem
If @Mapperscan scans all by default, and @SpringBoot scans all, is the object in this MapperFactoryBean or a real object?
One for @Service and one for MybatisScan for injected MapperFactoryBean
To solve
Again, it’s not about design, it’s about use
Why does Mybatis inject all classes according to the path in the scan package
If let you design, how do you know that the class scanned is not the class MyBatis needs to inject?
Special said
This method is already supported by @mapper, and does not need to scan, the default load, if you use @mapperscan, it is really redundant
Only Mapper packets are scanned
The problem is, if you’re just using it, if you don’t think about it, you’re probably just going to scan a big bag. There will be problems
Personal advice
In fact, personal advice can be automatic try not to manual. Because the supplier has prepared very well for the automatic, there will be no problem, but just the manual part will have some artificial omission or thoughtless or unable to achieve problems, resulting in the user does not know the end of the
So I think the best way is @Mapper, automatic