简述使用spring整合mybatis的基本步骤,springboot整合mybatis原理

  简述使用spring整合mybatis的基本步骤,springboot整合mybatis原理

  00-1010前言:简单猜测。通过扫描界面正式开始案例建设。SetBeannameSetApplicationContextAfterPropertieSpot processbean definition注册表摘要

  

目录

最近看了Spring的IOC部分的源代码,受益匪浅。本文解释了MyBatis如何与Spring集成。MyBatis是如何干扰Spring的生命周期,并把Mapper逐个注册到Spring容器中的,这里就要揭晓了。

 

  00-1010因为看了Spring的源代码对它有了一定的了解,所以在这里可以做一个简单的盲猜,用的是什么方法,在上一篇揭示Autowired的注解里有介绍。我们只是在xml中写了一行context : annotation-config/configuration。Spring就像用BeanFatory写的BeanPostProcessor,我觉得这里采用的函数都差不多。通过定义spring.handlers文件。然后mybatis定义了各种处理标签的处理器和Paser。然后,通过读取配置文件中的mappers标记,我们在寄存器中注册BeanDefinition,这是其中之一。

  第二种方法类似于AutoWiredAnnotation BeanPostProcessor的实现,它通过Xml注册一个Bean。此Bean继承自MergedBeanFinitionPostProcessor,因此它将优先运行Bean,因为它继承自MegedBeanFinitionPostProcessor。这时可以像bean factory一样添加Bean定义。

  其实我们的目标很明确。只要我们能在Spring调用InitiazionBean方法之前,将mapper的BeanDefinition添加到Spring容器中,就能达到当前的目标。

  那么我们来看看MyBatis本身是如何实现的。

  00-1010源地址:MyBatis集成Spring有两种方式。第一种是通过Xml,第二种是通过Mapper接口扫描。这里不演示具体的集成方法,只看配置文件。实际上,application.xml中有一点小小的变化.

  

前言

这里搭建一个最简单的整合方式:

 

  00-1010通过上面的配置文件,可以看到其中一个配置了名称scannerConfigurer。来,先看看这个类。

  公共类MapperScannerConfigurer实现bean definitionregistrypostprocessor、InitializingBean、ApplicationContextAware、BeanNameAware {这个类继承了几个接口:

  bean definitionregistrypostprocessor,接口,进去发现是从BeanFactoryPostProcessor继承的,也就是说spring在refresh方法中有一个方法可以执行这种接口。InitializingBean在createBean的生命周期中调用接口的afterProperties方法。创建bean时,ApplicationContextAwareSpring将调用setapplicationContext方法来注入上下文Beanname Aware。创建就是调用setBeanName方法,按照这样的接口执行的顺序是,setBeanName-setApplicationContext-after properties-postprocessbeandeditionregistry

  

简单猜想

@ override public void set bean name(String name){ this . bean name=name;}这个方法显然不是。

 

  

案例搭建

@ override public void setApplicationContext(application context application context){

 

  this.applicationContext = applicationContext;}这个方法很明显,也不是。

  

 

  

afterProperties

@Overridepublic void afterPropertiesSet() throws Exception { notNull(this.basePackage, "Property basePackage is required");}

 

  这个方法是用来校验的,判断了basePackage是否为空,如果为空就throw Exception。

  

 

  

postProcessBeanDefinitionRegistry

@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { if (this.processPropertyPlaceHolders) { processPropertyPlaceHolders(); } ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); scanner.setAddToConfig(this.addToConfig); scanner.setAnnotationClass(this.annotationClass); scanner.setMarkerInterface(this.markerInterface); scanner.setSqlSessionFactory(this.sqlSessionFactory); scanner.setSqlSessionTemplate(this.sqlSessionTemplate); scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName); scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName); scanner.setResourceLoader(this.applicationContext); scanner.setBeanNameGenerator(this.nameGenerator); scanner.setMapperFactoryBeanClass(this.mapperFactoryBeanClass); if (StringUtils.hasText(lazyInitialization)) { scanner.setLazyInitialization(Boolean.valueOf(lazyInitialization)); } if (StringUtils.hasText(defaultScope)) { scanner.setDefaultScope(defaultScope); } scanner.registerFilters(); scanner.scan( StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));}

那这里就很明显了,这里创建ClassPathMapperScanner。随后对scanner的一些配置做了一些设置。

 

  然后就调用了registerFilters方法,字面意思也就是注册过滤器,这里就跳过吧,无非是设置一些属性,然后在后面解析的时候判断过滤条件,在循环时continue。

  主要是scan方法这里要详细看一下:

  

public int scan(String... basePackages) { int beanCountAtScanStart = this.registry.getBeanDefinitionCount(); this.doScan(basePackages); if (this.includeAnnotationConfig) { AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } return this.registry.getBeanDefinitionCount() - beanCountAtScanStart;}

这里这个扫描类其实是Spring中的类,ClassPathBeanDefinitionScanner,当中的scan方法。所以这里可能会有点眼熟,类似于创建Bean时,先获取一下创建之前的Bean总数,然后再获取创建之后的Bean总数,返回时减一下就知道这次创建了多少。

 

  

 

  

总结

其实到这里呢,我们就算是结束了,因为后续的包扫描,在严格意义上来讲是Spring来实现的,我后续开篇文章来讲解这个东西。

 

  这里总结一下,正如我猜想的一样,myBatis只要在finishBeanFactoryInitialization方法之前,把Mapper的BeanDefinition塞进Spring容器中,在最后的finishBeanFactoryInitialization方法,Spring自然就会根据BeanDefinition去创建Bean了。

  这里使用的方法是,注册一个BeanFactoryPostProcessor,所以这个方法会在finishBeanFactoryInitialization方法之前运行,所以这里是成功的。

  到此这篇关于Spring和Mybatis整合的原理详解的文章就介绍到这了,更多相关Spring和Mybatis整合内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: