我们在使用mybatis时只定义了类似 ActorMapper 的接口,并没有编写实现这个接口的类,实际上mybatis在初始化时生成了这个接口的代理对象,这篇文章分析下mybatis在何时完成的这件事。
通过 org.apache.ibatis.session.SqlSession.getMapper 方法我们可以获得对象接口的代理类,下面分析下这段代码:
ActorMapper actorMapper = session.getMapper(ActorMapper.class);
org.apache.ibatis.session.defaults.DefaultSqlSession getMapper 方法,从以下代码可知,实际执行的是 configuration 的 getMapper 方法:
public T getMapper(Class type) {
return this.configuration.getMapper(type, this);
}
org.apache.ibatis.session.Configuration getMapper 方法,如下 configuration调用的是 configuration 属性 MapperRegistry mapperRegistry 的方法,mapperRegistry 是在 org.apache.ibatis.builder.xml.XMLConfigBuilder 构造方法中初始化 Configuration过程中初始化的
public T getMapper(Class type, SqlSession sqlSession) {
return this.mapperRegistry.getMapper(type, sqlSession);
}
org.apache.ibatis.binding.MapperRegistry
解析完 *Mapper.xml 后,MapperRegistry 中 knownMappers 属性已经填充好了对应 接口和 MapperProxyFactory 的键值对
public class MapperRegistry {
private final Configuration config;
private final Map, MapperProxyFactory>> knownMappers = new HashMap();
public T getMapper(Class type, SqlSession sqlSession) {
MapperProxyFactory mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
// 生成 Mapper 的代理对象
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}
}
org.apache.ibatis.binding.MapperProxyFactory
package org.apache.ibatis.binding;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.ibatis.binding.MapperProxy.MapperMethodInvoker;
import org.apache.ibatis.session.SqlSession;
public class MapperProxyFactory {
private final Class mapperInterface;
private final Map methodCache = new ConcurrentHashMap();
public MapperProxyFactory(Class mapperInterface) {
this.mapperInterface = mapperInterface;
}
public Class getMapperInterface() {
return this.mapperInterface;
}
public Map getMethodCache() {
return this.methodCache;
}
protected T newInstance(MapperProxy mapperProxy) {
// 通过JDK动态代理的方式生成代理对象
return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}
// 生成代理对象
public T newInstance(SqlSession sqlSession) {
MapperProxy mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
return this.newInstance(mapperProxy);
}
}
org.apache.ibatis.binding.MapperProxy
如下:MapperProxy 实现了 InvocationHandler 接口
public class MapperProxy implements InvocationHandler, Serializable {
private static final long serialVersionUID = -4724728412955527868L;
private static final int ALLOWED_MODES = 15;
private static final Constructor lookupConstructor;
private static final Method privateLookupInMethod;
private final SqlSession sqlSession;
private final Class mapperInterface;
private final Map methodCache;
public MapperProxy(SqlSession sqlSession, Class mapperInterface, Map methodCache) {
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
this.methodCache = methodCache;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return Object.class.equals(method.getDeclaringClass()) ? method.invoke(this, args) : this.cachedInvoker(method).invoke(proxy, method, args, this.sqlSession);
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
}
}
当执行 selectOneActor 方法时实际调用 MapperProxy invoke 方法,最终从 configuration 中获取 SQL 并替换参数执行
public List selectList(String statement, Object parameter, RowBounds rowBounds) {
List var5;
try {
MappedStatement ms = this.configuration.getMappedStatement(statement);
var5 = this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception var9) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + var9, var9);
} finally {
ErrorContext.instance().reset();
}
return var5;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)