目录
1. 前言
本篇文章是 Spring
整合 MyBatis
原理的第三篇文章,上一篇文章 在这里 ,我们啦继续学习 Spring
整合 MyBatis
原理
2. Mapper
接口代理对象的产生以及调用
2.1. Mapper
接口代理对象的产生
2.1.1. SqlSessionTemplate
中的 getMapper()
我们知道在 MyBatis
使用中,有如下步骤
public static void main(String[] args) throws Exception {
Reader reader = Resources.getResourceAsReader("resource/mybatis-config.xml");
// 获取 SqlSessionFactory 对象
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 获取 SqlSession 对象
SqlSession sqlSession = sessionFactory.openSession();
PersonDao personDao = sqlSession.getMapper(PersonDao.class);
Person person = new Person("11", "Fighter168");
personDao.save(person);
// ......省略
}
- 由
sqlSession.getMapper()
可知,它必定会产生代理对象,那么就开始分析它的背后逻辑 - 在
Spring
整合MyBatis
中,由于SqlSession
是线程不安全的,所以Spring
提供了一个SqlSessionTemplate
来代替SqlSession
,SqlSessionTemplate
类实现了SqlSession
接口 SqlSessionTemplate
中的getMapper()
方法如下
@Override
public <T> T getMapper(Class<T> type) {
return getConfiguration().getMapper(type, this);
}
@Override
public Configuration getConfiguration() {
return this.sqlSessionFactory.getConfiguration();
}
我们继续跟近 Configuration
类的 getMapper()
方法看下里面做了什么
2.1.2. Configuration
类的 getMapper()
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
继续跟进 MapperRegistry
类中的 getMapper()
2.1.3. MapperRegistry
类中的 getMapper()
@SuppressWarnings("unchecked")
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
// 获取已经解析完成的 Mapper 接口信息
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
// 实例化对象
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
knownMappers.get()
方法:获取已经解析完成了的Mapper
接口信息
显然,应该跟进 mapperProxyFactory.newInstance()
方法
2.1.4. MapperProxyFactory
类中的 newInstance()
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
// 调用下面的 newInstance()
return newInstance(mapperProxy);
}
@SuppressWarnings("unchecked")
protected T newInstance(