这个问题:估计大家都知道是动态代理。可是除了动态代理这之间还有哪些设计模式呢?
//3、获取mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//4、执行数据库操作,并处理结果集
return userMapper.selectUser("10");
先看我们的getMapper方法,是如何返回一个代理对象的。
@Override
public <T> T getMapper(Class<T> type) {
return configuration.getMapper(type, this);
}
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
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);
}
}
先从配置对象configuration中获取,最后委托给mapperRegistry对象。
在mapperRegistry中,有个缓存(knownMappers)对象Map,我们根据key(接口的全限定类名,比如:learn.UserMapper)去获取我们的MapperProxyFactory对象,MapperProxyFactory负责每次创建我们的代理对象的实例。
从这里,我们可以学到缓存和工厂的使用,这样做的好处,很明显,避免了资源的重复加载,可以重复利用我们的资源。
我们的MapperProxyFactory对象是在我们,创建configuration对象的过程中,解析xml生成并缓存起来的。
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;
/**
* @author Lasse Voss
*/
public class MapperProxyFactory<T> {
//就是我们的接口 比如:learn.UserMapper
private final Class<T> mapperInterface;
//用于缓存我们的方法调用,我们的同一个方法每次调用时