Proxy 对象创建
问题
sqlSession.getMapper(UserMapper.class) 是如何生成的代理对象?
Mapper 代理方式初始化完成后,下一步进行获取代理对象来执行
public class MybatisTest {
@Test
public void test2 ( ) throws IOException {
. . .
UserMapper mapperProxy = sqlSession. getMapper ( UserMapper . class ) ;
. . .
}
}
当调用 getMapper() 时,DefaultSqlSession 实际会委托 Configuration 来获取 Mapper 代理对象
public class DefaultSqlSession implements SqlSession {
private final Configuration configuration;
. . .
@Override
public < T > T getMapper ( Class < T > type) {
return configuration. getMapper ( type, this ) ;
}
}
Configuration 对象又会通过 MapperRegistry 获取 Mapper 代理对象
public class Configuration {
protected final MapperRegistry mapperRegistry = new MapperRegistry ( this ) ;
. . .
public < T > T getMapper ( Class < T > type, SqlSession sqlSession) {
return mapperRegistry. getMapper ( type, sqlSession) ;
}
}
MapperRegistry 中,会通过 knownMappers 获取 Mapper 代理对象工厂,然后通过 Mapper 代理对象工厂生成 Mapper 代理对象
public class MapperRegistry {
private final Map < Class < ? > , MapperProxyFactory < ? > > knownMappers = new HashMap < > ( ) ;
. . .
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 会创建MapperProxy 对象,封装相应参数,然后使用 JDK 动态代理方式,生成代理对象
public class MapperProxyFactory < T > {
private final Class < T > mapperInterface;
private final Map < Method , MapperMethodInvoker > methodCache = new ConcurrentHashMap < > ( ) ;
. . .
@SuppressWarnings ( "unchecked" )
protected T newInstance ( MapperProxy < T > mapperProxy) {
return ( T ) Proxy . newProxyInstance ( mapperInterface. getClassLoader ( ) , new Class [ ] { mapperInterface } , mapperProxy) ;
}
public T newInstance ( SqlSession sqlSession) {
final MapperProxy < T > mapperProxy = new MapperProxy < > ( sqlSession, mapperInterface, methodCache) ;
return newInstance ( mapperProxy) ;
}
}
总结