前言:
前面我们从源码层面梳理了 SqlSessionFactory、SqlSession 的创建过程,本篇我们继续分析一下 Mapper 的的获取过程。
MyBatis 源码分析--SqlSessionFactory
案例代码:
java
public class MyBatisTest {
@Test
public void test() throws IOException {
//读取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//创建 SqlSessionFactoryBuilder 对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//通过 SqlSessionBuilder 对象 解析 mybatis-config.xml 文件 构建一个SqlSessionFactory
SqlSessionFactory sqlSessionFactory = builder.build(is);
//通过SqlSessionFactory构建一个SqlSession
SqlSession session = sqlSessionFactory.openSession();
//通过SqlSession 获取 Mapper 实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//获取数据
List<User> users = userMapper.findAll();
//打印输出
for (User user : users) {
System.out.println(user);
}
//关闭资源
session.close();
is.close();
}
}
本篇我们将主要对 session.getMapper(UserMapper.class); 这句代码进行分析。
DefaultSqlSession#getMapper 源码分析
java
//org.apache.ibatis.session.defaults.DefaultSqlSession#getMapper
public <T> T getMapper(Class<T> type) {
return this.configuration.getMapper(type, this);
}
//org.apache.ibatis.session.Configuration#getMapper
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return this.mapperRegistry.getMapper(type, sqlSession);
}
MapperRegistry#getMapper 源码分析
java
//org.apache.ibatis.binding.MapperRegistry#getMapper
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//根据 class 获取 Mapper 代理工厂
MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
//使用 Mapper 代理工厂创建 Mapper 代理对象返回
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}
//org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.session.SqlSession)
public T newInstance(SqlSession sqlSession) {
//Mapper 代理
MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
//创建 Mapper 代理对象
return this.newInstance(mapperProxy);
}
//org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.binding.MapperProxy<T>)
protected T newInstance(MapperProxy<T> mapperProxy) {
//使用 JDK 创建一个 Mapper 的代理对象
return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}
从源码可以看出,获取 Mapper 其实就是根据 Mapper 的 Class 类型从 MapperRegistry 中获取一个 MapperProxyFactory,最终调用 MapperProxyFactory.newInstance 方法创建一个代理对象,生成一个代理类来调用 Mapper 的方法,这里的 MapperProxyFactory 其实就是在获取 SqlSessionFactory 中存入 MapperRegistry 的 MapperProxyFactory。
欢迎提出建议及对错误的地方指出纠正。