MyBatis创建动态代理类源码流程

总结

调用的getMapper方法(1)调用ConfigurationgetMapper方法(2)调用MapperRegistrygetMapper方法(3)调用MapperProxyFactory的newInstance方法(4)调用兄弟newInstance方法(6)使用动态代理模式去设置mapperProxy为目标Dao方法的代理(7),MapperProxy这个类中的invoke实现是利用MapperMethod的execute来执行的(19)

源码片段

已省略部分细节,只保留了主要方法调用。上文的括号中数字对应源码行数。

sqlSession.getMapper(){//去DefaultSqlSession
    return configuraion.<T>getMapper(type,this) {//去Configuration.java
        return mapperRegistry.getMapper(type, sqlSession) {//去MapperRegistry.java
            return mapperProxyFactory.newInstance(sqlSession){//去MapperProxyFactory.java
                final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
                return newInstance(mapperProy) {//兄弟方法
                    return (T)Proxy.newProxyInstance(mapperInterface.getClassLoader(),new Class[]{mapperInterface},mapperProxy/*加强Dao接口的代理类MapperProxy的对象*/))
                }
            }
        }
    }
}

class MapperProxy<T> implements InvocationHandler, Serializable{
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        ...
        final MapperMethod mapperMethod = cacheMapperMethod(method);
        return mapperMethod.execute(sqlSession, args){//去MapperMethod.java
            Object result;
            switch (command.getType()) {
              case INSERT: {
               Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.insert(command.getName(), param));
                break;
              }
              case UPDATE: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.update(command.getName(), param));
                break;
              }
              case DELETE: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.delete(command.getName(), param));
                break;
              }
              case SELECT:
                if (method.returnsVoid() && method.hasResultHandler()) {
                  executeWithResultHandler(sqlSession, args);
                  result = null;
                } else if (method.returnsMany()) {
                  result = executeForMany(sqlSession, args);
                } else if (method.returnsMap()) {
                  result = executeForMap(sqlSession, args);
                } else if (method.returnsCursor()) {
                  result = executeForCursor(sqlSession, args);
                } else {
                  Object param = method.convertArgsToSqlCommandParam(args);
                  result = sqlSession.selectOne(command.getName(), param);
                }
                break;
              case FLUSH:
                result = sqlSession.flushStatements();
                break;
              default:
                throw new BindingException("Unknown execution method for: " + command.getName());
            }
            if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
              throw new BindingException("Mapper method '" + command.getName() 
                  + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
            }
            return result;            
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值