# MethodSignature - Author: [HuiFer](https://github.com/huifer) - Description: 该文介绍 mybatis MethodSignature 类 - 源码阅读工程: [SourceHot-Mybatis](https://github.com/SourceHot/mybatis-read.git) - `org.apache.ibatis.binding.MapperMethod.MethodSignature` ```java /** * 方法签名 */ public static class MethodSignature { /** * 返回值是否多个 */ private final boolean returnsMany; /** * 返回值是不是map */ private final boolean returnsMap; /** * 返回值是否 void */ private final boolean returnsVoid; /** * 返回的是否是一个游标 */ private final boolean returnsCursor; /** * 返回值是否是 optional */ private final boolean returnsOptional; /** * 返回类型 */ private final Class returnType; /** * map key */ private final String mapKey; private final Integer resultHandlerIndex; private final Integer rowBoundsIndex; /** * 参数解析 */ private final ParamNameResolver paramNameResolver; public MethodSignature(Configuration configuration, Class mapperInterface, Method method) { Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface); if (resolvedReturnType instanceof Class) { this.returnType = (Class) resolvedReturnType; } else if (resolvedReturnType instanceof ParameterizedType) { this.returnType = (Class) ((ParameterizedType) resolvedReturnType).getRawType(); } else { this.returnType = method.getReturnType(); } this.returnsVoid = void.class.equals(this.returnType); this.returnsMany = configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray(); this.returnsCursor = Cursor.class.equals(this.returnType); this.returnsOptional = Optional.class.equals(this.returnType); this.mapKey = getMapKey(method); this.returnsMap = this.mapKey != null; this.rowBoundsIndex = getUniqueParamIndex(method, RowBounds.class); this.resultHandlerIndex = getUniqueParamIndex(method, ResultHandler.class); this.paramNameResolver = new ParamNameResolver(configuration, method); } /** * 方法主要是把方法参数转换为SQL命令参数。 * * @param args * @return */ public Object convertArgsToSqlCommandParam(Object[] args) { return paramNameResolver.getNamedParams(args); } /** * 是否有 {@link RowBounds} * * @return */ public boolean hasRowBounds() { return rowBoundsIndex != null; } public RowBounds extractRowBounds(Object[] args) { return hasRowBounds() ? (RowBounds) args[rowBoundsIndex] : null; } /** * 是否uresultHandler * * @return */ public boolean hasResultHandler() { return resultHandlerIndex != null; } public ResultHandler extractResultHandler(Object[] args) { return hasResultHandler() ? (ResultHandler) args[resultHandlerIndex] : null; } public String getMapKey() { return mapKey; } public Class getReturnType() { return returnType; } public boolean returnsMany() { return returnsMany; } public boolean returnsMap() { return returnsMap; } public boolean returnsVoid() { return returnsVoid; } public boolean returnsCursor() { return returnsCursor; } /** * return whether return type is {@code java.util.Optional}. * * @return return {@code true}, if return type is {@code java.util.Optional} * @since 3.5.0 */ public boolean returnsOptional() { return returnsOptional; } /** * 获取参数名 * {@link RowBounds} * * @param method mapper 方法 * @param paramType * @return */ private Integer getUniqueParamIndex(Method method, Class paramType) { Integer index = null; // 获取参数类型 final Class[] argTypes = method.getParameterTypes(); for (int i = 0; i < argTypes.length; i++) { if (paramType.isAssignableFrom(argTypes[i])) { if (index == null) { index = i; } else { throw new BindingException(method.getName() + " cannot have multiple " + paramType.getSimpleName() + " parameters"); } } } return index; } /** * 获取 {@link MapKey} 注解数据 * * @param method * @return */ private String getMapKey(Method method) { String mapKey = null; if (Map.class.isAssignableFrom(method.getReturnType())) { final MapKey mapKeyAnnotation = method.getAnnotation(MapKey.class); if (mapKeyAnnotation != null) { mapKey = mapKeyAnnotation.value(); } } return mapKey; } } ```