MethodSignature

  • Author: HuiFer
  • Description: 该文介绍 mybatis MethodSignature 类
  • 源码阅读工程: SourceHot-Mybatis
  • org.apache.ibatis.binding.MapperMethod.MethodSignature
  1. /**
  2. * 方法签名
  3. */
  4. public static class MethodSignature {
  5. /**
  6. * 返回值是否多个
  7. */
  8. private final boolean returnsMany;
  9. /**
  10. * 返回值是不是map
  11. */
  12. private final boolean returnsMap;
  13. /**
  14. * 返回值是否 void
  15. */
  16. private final boolean returnsVoid;
  17. /**
  18. * 返回的是否是一个游标
  19. */
  20. private final boolean returnsCursor;
  21. /**
  22. * 返回值是否是 optional
  23. */
  24. private final boolean returnsOptional;
  25. /**
  26. * 返回类型
  27. */
  28. private final Class<?> returnType;
  29. /**
  30. * map key
  31. */
  32. private final String mapKey;
  33. private final Integer resultHandlerIndex;
  34. private final Integer rowBoundsIndex;
  35. /**
  36. * 参数解析
  37. */
  38. private final ParamNameResolver paramNameResolver;
  39. public MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) {
  40. Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface);
  41. if (resolvedReturnType instanceof Class<?>) {
  42. this.returnType = (Class<?>) resolvedReturnType;
  43. } else if (resolvedReturnType instanceof ParameterizedType) {
  44. this.returnType = (Class<?>) ((ParameterizedType) resolvedReturnType).getRawType();
  45. } else {
  46. this.returnType = method.getReturnType();
  47. }
  48. this.returnsVoid = void.class.equals(this.returnType);
  49. this.returnsMany = configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray();
  50. this.returnsCursor = Cursor.class.equals(this.returnType);
  51. this.returnsOptional = Optional.class.equals(this.returnType);
  52. this.mapKey = getMapKey(method);
  53. this.returnsMap = this.mapKey != null;
  54. this.rowBoundsIndex = getUniqueParamIndex(method, RowBounds.class);
  55. this.resultHandlerIndex = getUniqueParamIndex(method, ResultHandler.class);
  56. this.paramNameResolver = new ParamNameResolver(configuration, method);
  57. }
  58. /**
  59. * 方法主要是把方法参数转换为SQL命令参数。
  60. *
  61. * @param args
  62. * @return
  63. */
  64. public Object convertArgsToSqlCommandParam(Object[] args) {
  65. return paramNameResolver.getNamedParams(args);
  66. }
  67. /**
  68. * 是否有 {@link RowBounds}
  69. *
  70. * @return
  71. */
  72. public boolean hasRowBounds() {
  73. return rowBoundsIndex != null;
  74. }
  75. public RowBounds extractRowBounds(Object[] args) {
  76. return hasRowBounds() ? (RowBounds) args[rowBoundsIndex] : null;
  77. }
  78. /**
  79. * 是否uresultHandler
  80. *
  81. * @return
  82. */
  83. public boolean hasResultHandler() {
  84. return resultHandlerIndex != null;
  85. }
  86. public ResultHandler extractResultHandler(Object[] args) {
  87. return hasResultHandler() ? (ResultHandler) args[resultHandlerIndex] : null;
  88. }
  89. public String getMapKey() {
  90. return mapKey;
  91. }
  92. public Class<?> getReturnType() {
  93. return returnType;
  94. }
  95. public boolean returnsMany() {
  96. return returnsMany;
  97. }
  98. public boolean returnsMap() {
  99. return returnsMap;
  100. }
  101. public boolean returnsVoid() {
  102. return returnsVoid;
  103. }
  104. public boolean returnsCursor() {
  105. return returnsCursor;
  106. }
  107. /**
  108. * return whether return type is {@code java.util.Optional}.
  109. *
  110. * @return return {@code true}, if return type is {@code java.util.Optional}
  111. * @since 3.5.0
  112. */
  113. public boolean returnsOptional() {
  114. return returnsOptional;
  115. }
  116. /**
  117. * 获取参数名
  118. * {@link RowBounds}
  119. *
  120. * @param method mapper 方法
  121. * @param paramType
  122. * @return
  123. */
  124. private Integer getUniqueParamIndex(Method method, Class<?> paramType) {
  125. Integer index = null;
  126. // 获取参数类型
  127. final Class<?>[] argTypes = method.getParameterTypes();
  128. for (int i = 0; i < argTypes.length; i++) {
  129. if (paramType.isAssignableFrom(argTypes[i])) {
  130. if (index == null) {
  131. index = i;
  132. } else {
  133. throw new BindingException(method.getName() + " cannot have multiple " + paramType.getSimpleName() + " parameters");
  134. }
  135. }
  136. }
  137. return index;
  138. }
  139. /**
  140. * 获取 {@link MapKey} 注解数据
  141. *
  142. * @param method
  143. * @return
  144. */
  145. private String getMapKey(Method method) {
  146. String mapKey = null;
  147. if (Map.class.isAssignableFrom(method.getReturnType())) {
  148. final MapKey mapKeyAnnotation = method.getAnnotation(MapKey.class);
  149. if (mapKeyAnnotation != null) {
  150. mapKey = mapKeyAnnotation.value();
  151. }
  152. }
  153. return mapKey;
  154. }
  155. }