ibatis-binding-MapperMethod
ibatis-binding-MapperMethod
核心方法:execute
执行接口方法对应的SQL语句。
把Mapper接口中的每个方法封装为MapperMethod对象,MapperMethod下包含SqlCommand与MethodSignature
其中SqlCommand为方法对应的SQL名称和SQL类型。
MethodSignature为SQL的详细信息,包括returnsMany、returnsOptional、resultHandlerIndex、paramNameResolver等
MapperProxy实现了InvocationHandler接口,使用cglib代理方式?
为什么使用cglib代理方式?因为mapper接口没有对应的接口,无法使用动态代理方式,只能使用cglib代理,即通过代码增强的方式生成子类,通过子类调用mapper接口的方法。
1、SqlSessionFactoryBuilder调用 build(Reader reader, String environment, Properties properties),再调用build(XMLConfigBuilder parser.parse())
2、XMLConfigBuilder调用Configuration parse(),再调用parseConfiguration(parser.evalNode("/configuration")),再调用mappersElement(root.evalNode("mappers")),内部调用configuration.addMappers(mapperPackage)
3、Configuration调用addMappers(String packageName),内部调用mapperRegistry.addMappers(packageName)
4、MapperRegistry调用getMapper(Class<T> type, SqlSession sqlSession),内部调用mapperProxyFactory.newInstance(sqlSession)
5、MapperRegistry调用addMappers(String packageName, Class<?> superType),内部调用knownMappers.put(type, new MapperProxyFactory<>(type)),根据type增加MapperProxyFactory
6、MapperProxyFactory提供新建实例newInstance(SqlSession sqlSession),创建MapperProxy实例
7、MapperProxy调用invoke方法,内部mapperMethod.execute(sqlSession, args)代码
8、mapperMethod.execute(sqlSession, args)调用MapperMethod的execute方法
MapperProxyFactory通过Proxy.newProxyInstance 代理方式生成MapperProxy对应的子类,MapperProxy实现了InvocationHandler接口(使用cglib代理)
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> { // mapper的接口类型 private Class<T> mapperInterface; @Override public T getObject() throws Exception { // 通过SqlSession获取接口的动态搭理对象 return getSqlSession().getMapper(this.mapperInterface); } @Override public Class<T> getObjectType() { return this.mapperInterface; } }
getObject方法的实现就是返回通过SqlSession获取到的Mapper接口的动态代理对象。
而@MapperScan注解的作用就是将每个接口对应的MapperFactoryBean注册到Spring容器的。