版本说明:mybatis3.4.0
一、获取mapper
SqlSession sqlSession = sqlSessionFactory.openSession();
AbcMapper abcMapper = sqlSession.getMapper(AbcMapper.class);
public class DefaultSqlSession implements SqlSession {
//....
public <T> T getMapper(Class<T> type) {
return this.configuration.getMapper(type, this);
}
//....
}
public class Configuration {
//...
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {//从之前配置解析注册的mapper中,拿到mapper
return this.mapperRegistry.getMapper(type, sqlSession);
}
//...
}
public class MapperRegistry {
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}
}
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap();
//....生成动态代理对象,实质上拿到的mapper是MapperProxy<T>代理对象,
protected T newInstance(MapperProxy<T> mapperProxy) {
return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
return this.newInstance(mapperProxy);
}
}
二、MapperProxy动态代理的实现
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 Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {//如果执行的是Object的方法则执行原方法
try {
return method.invoke(this, args);
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
} else {
MapperMethod mapperMethod = this.cachedMapperMethod(method);
//其实你执行mapper的时候、也就是执行了mybatis封装的一个MapperMethod、
//并且把sqlSession和执行的方法参数执行execute方法
return mapperMethod.execute(this.sqlSession, args);
}
}
private MapperMethod cachedMapperMethod(Method method) {
MapperMethod mapperMethod = (MapperMethod)this.methodCache.get(method);
if (mapperMethod == null) {
//该MapperMethod就是根据执行方法名在Configuration中和取出的信息。
mapperMethod = new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration());
this.methodCache.put(method, mapperMethod);
}
return mapperMethod;
}
}
其实MapperMethod中储存了MappedStatement的id和类型、方便使用sqlSession执行MappedStatement
mapperMethod.execute(this.sqlSession, args);