springboot加mybatis(java spring , mybatis, spring boot ,spring mvc 都是什么)

本文目录
- java spring , mybatis, spring boot ,spring mvc 都是什么
- springboot中,mybatis的mapper接口是如何生成代理对象的
- 在 springboot 中进行单独的 mybatis 单元测试
java spring , mybatis, spring boot ,spring mvc 都是什么
1.1、Spring
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
1.2、SpringMVC
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
1.3、MyBatis
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。MyBatis是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
springboot中,mybatis的mapper接口是如何生成代理对象的
引入了以下包
其中自动装配的包就是mybatis-spring-boot-autoconfigure。
META-INF下有一个spring.factories文件
导入了这个类MybatisAutoConfiguration
注册MapperScannerConfigurer的Bean定义到Spring容器中,并设置扫描包的路径
MapperScannerConfigurer 实现BeanDefinitionRegistryPostProcessor接口,实例化的时候会调到postProcessBeanDefinitionRegistry方法,这个方法里会创建一个ClassPathMapperScanner对象,然后去扫描
扫描到之后修改BeanDefinition
@MapperScan注解,会import进来MapperScannerRegistrar这个类
MapperScannerRegistrar类实现ImportBeanDefinitionRegistrar接口,实例化的时候会调用registerBeanDefinitions方法
和@Mapper一样,同样会创建MapperScannerConfigurer的BeanDefition,用于后续实例化
只不过要扫描的包路径变了,不再是默认的,而是@MapperScan配置的包路径
后面的话则和@Mapper扫描到之后的工作原理是一样的,扫描到之后,更改BeanDefinition,一毛一样的。
==可以看出@MapperScan最主要的工作原理除了提供BasePackage的值之外,就是用@Import注解导入MapperScannerRegistrar.所以这个注解打在任何可以被spring扫描到的类上都可以,并不一定要打在启动类上(大多数为了只是为了看起来方便,把全局性的配置注解打在启动类上而已)==
前面提到,注册扫描@Mapper接口的MapperScannerConfigurer实例的类是AutoConfiguredMapperScannerRegistrar,那么这个类是如何被导入进来的呢
MybatisAutoConfiguration还有一个静态内部类,@Import了AutoConfiguredMapperScannerRegistrar类,但是有@ConditionalOnMissingBean,即spring容器中不存在MapperFactoryBean,MapperScannerConfigurer的实例。
如果@MapperScan注解生效,并且扫描到任意一个Mapper接口(前面被改造成MapperFactoryBean类型的了),那么就不满足注册这个类MapperScannerRegistrarNotFoundConfiguration的实例的条件,继而不会导入AutoConfiguredMapperScannerRegistrar类。
前面提到,所有的Mapper接口被扫描到,封装成BeanDefinition,还经历了一次改造,
最主要的就是将mapper接口BeanDefination的beanClass改成了org.mybatis.spring.mapper.MapperFactoryBean.class
并且将mapper接口BeanDefination的名称作为构造函数的入参传入进去
并讲BeanDefinition的autowireMode属性改成 AUTOWIRE_BY_TYPE ,后面实例化该bean的时候会调用属性的描述器,用write的方式注入属性值,最重要的那个属性那就是SqlSessionTemplate. 会通过这种方式将前面MybatisAutoConfiguration中@Bean出来的SqlSessionTemplate注入到其中。
类图:
这里他实现了FactoryBean,
FactoryBean有以下方法
这里是spring的一个拓展点,实现了FactoryBean接口的类,将可以实现getObject() 和getObjectType来实例化额外的一个bean并装到spring容器中
好吧,其实Mapper代理对象的创建就是在MapperFactoryBean的getObject方法中返回的
这里就是熟悉的原生Mybatis创建Mapper接口的味道了。
附上调用的类时序图,回过头来看一下调用的整体流程。
在 springboot 中进行单独的 mybatis 单元测试
使用普通的@SpringBootTest进行单元测试时会将整个应用都启动,和正常启动工程没什么区别。非常耗时。
如下,启动测试。将web层也启动了。事实上根本不需要启动这个。
我们只需要启动dao就行了。在这里我们使用mybatis-spring-boot-starter-test这个依赖
测试例子
打印sql
1、java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
需要和springboot main方法放到同一级包下
2、Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate : Factory method ’dataSource’ threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
若依工程引入这个真的有点难,推荐还是使用@SpringBootTest的方式
普通单数据源请配置如下:spring.datasource.url的形式;否则单元测试启动报错’url’ attribute is not specified and no embedded datasource could be configured.
有多个数据源时才去配置这样,spring.datasource.druid.master.url;

本文相关文章:
websocket整合springboot(Springboot整合Websocket遇到的坑)
2026年10月11日 01:40
springboot启动原理总结(Spring boot Batch 的启动原理- Configuration)
2026年8月15日 09:30
用bootstrap做的网站(怎么使用bootstrap来开发网站)
2026年7月14日 21:40
更多文章:
teammate(teammate,company,partner)
2026年10月11日 06:10
javascript arraybuffer(javascript可以把base64编码转换成二进制代码吗求示例代码!)
2026年10月11日 04:00
text函数公式(excel中round和text函数的区别是什么)
2026年10月11日 03:50
google chrome打不开(chrome浏览器打不开怎么回事 浏览器打不开的处理方法)
2026年10月11日 02:00
websocket整合springboot(Springboot整合Websocket遇到的坑)
2026年10月11日 01:40
drawerlayout(android 怎样让drawerlayout设置的侧滑菜单的内容充满屏幕)
2026年10月10日 19:20
xor四位数怎么运算(单片机怎样用C语言实现4个数字间的异或)
2026年10月10日 17:50
perl数组中最多的元素(用perl实现,得到一个数组中重复次数最多的元素)
2026年10月10日 17:00




