Spring与Mybatis整合的MapperScannerConfigurer怎么用

73次阅读
没有评论

共计 3586 个字符,预计需要花费 9 分钟才能阅读完成。

这篇文章将为大家详细讲解有关 Spring 与 Mybatis 整合的 MapperScannerConfigurer 怎么用,丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

MapperScannerConfigurer 介绍

MapperScannerConfigurer 是 spring 和 mybatis 整合的 mybatis-spring jar 包中提供的一个类。

想要了解该类的作用,就得先了解 MapperFactoryBean。

MapperFactoryBean 的出现为了代替手工使用 SqlSessionDaoSupport 或 SqlSessionTemplate 编写数据访问对象 (DAO) 的代码, 使用动态代理实现。

比如下面这个官方文档中的配置:

bean id= userMapper   >

org.mybatis.spring.sample.mapper.UserMapper 是一个接口,我们创建一个 MapperFactoryBean 实例,然后注入这个接口和 sqlSessionFactory(mybatis 中提供的 SqlSessionFactory 接口,MapperFactoryBean 会使用 SqlSessionFactory 创建 SqlSession)这两个属性。

之后想使用这个 UserMapper 接口的话,直接通过 spring 注入这个 bean,然后就可以直接使用了,spring 内部会创建一个这个接口的动态代理。

当发现要使用多个 MapperFactoryBean 的时候,一个一个定义肯定非常麻烦,于是 mybatis-spring 提供了 MapperScannerConfigurer 这个类,它将会查找类路径下的映射器并自动将它们创建成 MapperFactoryBean。

 bean  >

这段配置会扫描 org.mybatis.spring.sample.mapper 下的所有接口,然后创建各自接口的动态代理类。

MapperScannerConfigurer 底层代码分析

以以下代码为示例进行讲解(部分代码,其他代码及配置省略):

package org.format.dynamicproxy.mybatis.dao;
public interface UserDao { public User getById(int id);
 public int add(User user); 
 public int update(User user); 
 public int delete(User user); 
 public List User  getAll(); 
 bean  >

我们先通过测试用例 debug 查看 userDao 的实现类到底是什么。

我们可以看到,userDao 是 1 个 MapperProxy 类的实例。
看下 MapperProxy 的源码,没错,实现了 InvocationHandler,说明使用了 jdk 自带的动态代理。

public class MapperProxy T  implements InvocationHandler, Serializable {
 private static final long serialversionUID = -6424540398559729838L;
 private final SqlSession sqlSession;
 private final Class T  mapperinterface;
 private final Map Method, MapperMethod  methodCache;
 public MapperProxy(SqlSession sqlSession, Class T  mapperInterface, Map Method, MapperMethod  methodCache) {
 this.sqlSession = sqlSession;
 this.mapperInterface = mapperInterface;
 this.methodCache = methodCache;
 }
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (Object.class.equals(method.getDeclaringClass())) {
 try { return method.invoke(this, args);
 } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t);
 }
 }
 final MapperMethod mapperMethod = cachedMapperMethod(method);
 return mapperMethod.execute(sqlSession, args);
 }
 private MapperMethod cachedMapperMethod(Method method) { MapperMethod mapperMethod = methodCache.get(method);
 if (mapperMethod == null) { mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
 methodCache.put(method, mapperMethod);
 }
 return mapperMethod;
 }
}

下面开始分析 MapperScannerConfigurer 的源码

MapperScannerConfigurer 实现了 BeanDefinitionRegistryPostProcessor 接口,BeanDefinitionRegistryPostProcessor 接口是一个可以修改 spring 工长中已定义的 bean 的接口,该接口有个 postProcessBeanDefinitionRegistry 方法。

然后我们看下 ClassPathMapperScanner 中的关键是如何扫描对应 package 下的接口的。

其实 MapperScannerConfigurer 的作用也就是将对应的接口的类型改造为 MapperFactoryBean,而这个 MapperFactoryBean 的属性 mapperInterface 是原类型。MapperFactoryBean 本文开头已分析过。

所以最终我们还是要分析 MapperFactoryBean 的实现原理!

MapperFactoryBean 继承了 SqlSessionDaoSupport 类,SqlSessionDaoSupport 类继承 DaoSupport 抽象类,DaoSupport 抽象类实现了 InitializingBean 接口,因此实例个 MapperFactoryBean 的时候,都会调用 InitializingBean 接口的 afterPropertiesSet 方法。

DaoSupport 的 afterPropertiesSet 方法:

MapperFactoryBean 重写了 checkDaoConfig 方法:

然后通过 spring 工厂拿对应的 bean 的时候:

这里的 SqlSession 是 SqlSessionTemplate,SqlSessionTemplate 的 getMapper 方法:

Configuration 的 getMapper 方法,会使用 MapperRegistry 的 getMapper 方法:

MapperRegistry 的 getMapper 方法:

MapperProxyFactory 构造 MapperProxy:

没错!MapperProxyFactory 就是使用了 jdk 组带的 Proxy 完成动态代理。
MapperProxy 本来一开始已经提到。MapperProxy 内部使用了 MapperMethod 类完成方法的调用:
Spring 与 Mybatis 整合的 MapperScannerConfigurer 怎么用

下面,我们以 UserDao 的 getById 方法来 debug 看看 MapperMethod 的 execute 方法是如何走的。

@Test
public void testGet() { int id = 1; system.out.println(userDao.getById(id));
 select id= getById

Spring 与 Mybatis 整合的 MapperScannerConfigurer 怎么用
Spring 与 Mybatis 整合的 MapperScannerConfigurer 怎么用

关于“Spring 与 Mybatis 整合的 MapperScannerConfigurer 怎么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计3586字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)