时间:2021-05-19
MyBatis 初始化过程就是生成一些必须的对象放到 Spring 容器中。问题是这个过程到底生成了哪些对象?当遇到 MyBatis 初始化失败时,如何正确的找到分析问题的切入点?本文将针对这些问题进行介绍。
本文基于 MyBatis 3 和 Spring,假设读者已经知道如何使用 Maven 和 MyBatis,以及了解 Spring 的容器机制。
一、Mybatis 三件套
我们知道 MyBatis 的主要功能是由 SqlSessionFactory 和 Mapper 两者提供的,初始化 MyBatis 就是初始化这两类对象。除此之外 DataSource 作为数据库访问对象也是必不可少。因此首先我们应该记住 MyBatis 初始化的核心三件套:
具体来说,一个简单的初始化过程就是下面这样:
@Configurationpublic class SpringMyBatisApplication { public static void main(String[] args) { new AnnotationConfigApplicationContext(SpringMyBatisApplication.class); } @Bean public DataSource dataSource() { return ...; } @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) { return ...; } @Bean public MapperScannerConfigurer mapperScannerConfigurer() { return ...; }}接下来介绍三件套各自如何初始化,下面的内容是可以实际操作的,不妨动手试试。
1. DataSource 初始化
首先我们创建一个空的 Maven 项目,在 pom.xml 中加入下面的依赖关系:
<!-- Spring --><dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.0.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.2.0.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.0.RELEASE</version></dependency><!-- 数据库 --><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.7.0</version></dependency><dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.199</version></dependency>本文重在演示 MyBatis 的初始化过程,所以没有复杂的 SQL,数据库用的是嵌入式数据库 h2。
然后我们在 com.hyd.mybatis3test 包下面创建一个 SpringMyBatisApplication 类,代码在前面给过了。
对应的 DataSource 初始化实现如下:
@Beanpublic DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUrl("jdbc:h2:mem:test"); return dataSource;}2. SqlSessionFactoryBean 初始化
SqlSessionFactoryBean 是对 SqlSessionFactory 初始化过程的封装,Spring 会在适当的时候执行这个初始化过程,得到最终的 SqlSessionFactory 对象。
SqlSessionFactoryBean 的创建过程如下(注意方法签名在前面的基础上有变动):
@Beanpublic SqlSessionFactoryBean sqlSessionFactory( DataSource dataSource, ResourcePatternResolver resolver) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(resolver.getResources("classpath*:mappers/*.xml")); return bean;}其中:
3. MapperScannerConfigurer 初始化
MapperScannerConfigurer 的职责是在指定路径下搜索所有的 Mapper 接口类(参考它的 postProcessBeanDefinitionRegistry() 方法),并通过 MapperFactoryBean 将其注册到 MapperRegistry 中。
@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage("com.hyd.mybatis3test"); return configurer;}4. 验证初始化过程成功
为了验证上面的初始化过程完成了,我们在 com.hyd.mybatis3test 包下面创建一个 Mapper 类:
@Mapperpublic interface SampleMapper { @Update("create table if not exists user(id int)") void createUserTable();}以及一个 Service 类:
@Servicepublic static class SampleService { @Autowired private SampleMapper sampleMapper; @PostConstruct public void init() { sampleMapper.createUserTable(); }}然后别忘了在 SpringMyBatisApplication 顶上添加一个 @ComponentScan("com.hyd.mybatis3test") 注解,否则 Spring 会找不到 SampleService。
运行 SpringMyBatisApplication.main() 方法,我们就能在输出中找到这样的内容:
...
SampleMapper.createUserTable - ==> Preparing: create table if not exists user(id int)
SampleMapper.createUserTable - ==> Parameters:
SampleMapper.createUserTable - <== Updates: 0
...
这说明这条创建表格的 SQL 语句成功执行了。
在前面三件套的基础上,MyBatis 也提供了更多的封装。有了本文上面的铺垫,相信读者对这些封装方式理解起来也会轻松很多。
二、@MapperScan 注解
@MapperScan 注解只不过是 MapperScannerConfigurer 的启动器而已,使用这个注解,可以代替前面的 MapperScannerConfigurer 初始化。
三、SpringBoot 自动初始化
MyBatis 提供 mybatis-spring-boot-starter 库用于在 Spring Boot 项目中自动初始化:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version></dependency>这个所谓的自动初始化实际上就是初始化 SqlSessionFactory 对象。初始化的过程由 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 完成,所需的配置都从 "mybatis-" 前缀的配置属性中获取,具体可以参考 org.mybatis.spring.boot.autoconfigure.MybatisProperties 类。
总结
总之,MyBatis 的初始化核心过程就是三件套的初始化。而在 Spring Boot 应用中,结合自动初始化和 @MapperScan 注解,我们无需手工初始化上这三件套,就能直接从容器中得到 Mapper 对象。
到此这篇关于理解 MyBatis 是如何在 Spring 容器中初始化的的文章就介绍到这了,更多相关mybatis在spring中的初始化内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
关于在spring容器初始化bean和销毁前所做的操作定义方式有三种:第一种:通过注解@PostConstruct和@PreDestroy方法实现初始化和销毁b
前言首先我们初始化一个最简单的容器,用这个容器研究初始化的流程。下面就是一个再简单不过的IoC容器了,该容器包含了一个名为beanA的bean,我们初始化容器后
BeanPostProcessor接口作用:如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个
BeanPostProcessor的接口定义,可以实现提供自己的实例化逻辑,依赖解析逻辑等,也可以以后在Spring容器实例化完毕,配置和初始化一个bean通过
关于延迟加载在Spring中,默认情况下所有定的bean及其依赖项目都是在应用启动时创建容器上下文是被初始化的。测试代码如下:@Slf4j@Configurat