2.9、mybatis源码分析之创建代理接口流程
2018-09-19 本文已影响0人
小manong
- mybatis创建代理接口其实在前面已经讲过了,这里以流程的形式加以回顾。可以参考前面的博文:https://www.jianshu.com/p/819a58df1168
- 创建代理接口入口:
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
一、MapperRegistry注册接口类中执行getMapper
- 前面分析了MapperRegistry是Mapper接口的注册管理类,当解析配置文件后会将相应的Mapper接口文件注册进入MapperRegistry中,现在从MapperRegistry根据类对象取出相对应的Mapper接口。
1、SqlSession中执行getMapper
@Override
public <T> T getMapper(Class<T> type) {
return configuration.<T>getMapper(type, this);
}
2、Configuration中执行getMapper
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
3、MapperRegistry中根据type执行getMapper
//代理接口和MapperProxyFactory工厂容器,前面configuration初始化已
//近完成了接口和MapperProxyFactory工厂绑定的
@SuppressWarnings("unchecked")
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
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);
}
}
二、mapperProxyFactory代理工厂创建相应的Mapper对象
//实现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 T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
//动态代理生成相应的Mapper接口代理接口mapperProxy
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
三、创建代理接口流程
-
实际返回的是MapperProxy代理对象,代理对象中包含了SqlSession等重要元素,保证能正常执行sql语句,当调用Mapper委托接口的方法的时候,会调用MapperProxy代理对象的invoke方法完成该方法逻辑。
创建代理接口流程