{"id":1078,"date":"2014-11-22T10:45:53","date_gmt":"2014-11-22T02:45:53","guid":{"rendered":"http:\/\/coderbee.net\/?p=1078"},"modified":"2014-11-27T22:36:44","modified_gmt":"2014-11-27T14:36:44","slug":"java-%e5%8f%8d%e5%b0%84-%e6%8a%bd%e5%8f%96%e7%b1%bb%e7%9a%84%e6%96%b9%e6%b3%95%e4%bf%a1%e6%81%af","status":"publish","type":"post","link":"https:\/\/coderbee.net\/index.php\/java\/20141122\/1078","title":{"rendered":"Java \u53cd\u5c04 \u62bd\u53d6\u7c7b\u7684\u65b9\u6cd5\u4fe1\u606f"},"content":{"rendered":"<p>\u76ee\u524d\u53c2\u4e0e\u7684\u9879\u76ee\u662f\u7528 Spring MVC + MyBatis \u5b9e\u73b0\u7684\uff0c\u9879\u76ee\u90e8\u7f72\u5c31\u662f\u4e00\u4e2awar\u5305\u3002\u516c\u53f8\u4ece\u5916\u9762\u8bf7\u4e86\u4e2a\u987e\u95ee\uff0c\u5efa\u8bae\u5c06\u516c\u53f8\u7f51\u7edc\u5206\u4e3aA\u3001B\u4e24\u4e2a\u533a\uff0cB\u533a\u7684\u5b89\u5168\u7ea7\u522b\u9ad8\u4e9b\uff0c\u53ef\u4ee5\u8bbf\u95ee\u6570\u636e\u5e93\uff0cA\u533a\u7684\u5b89\u5168\u7ea7\u522b\u4f4e\u4e9b\uff0c\u4e0d\u80fd\u8bbf\u95ee\u6570\u636e\u5e93\uff0c\u76f4\u63a5\u9762\u5411\u4e92\u8054\u7f51\uff0c\u5e94\u7528\u9700\u8981\u8bbf\u95ee\u5916\u90e8\u4e92\u8054\u7f51\u670d\u52a1\u65f6 \u6216 \u5916\u90e8\u7528\u6237\u8bf7\u6c42\u5e94\u7528\u65f6\u90fd\u5fc5\u987b\u5728 A \u533a\u5b8c\u6210\uff0cA\u533a\u901a\u8fc7\u5b9a\u5236\u7684\u7f51\u5173\u8bbf\u95ee B \u533a\u7684\u5e94\u7528\u3002\u8fd9\u4e2a\u5efa\u8bae\u662f\u5f3a\u5236\u6267\u884c\uff0c\u6240\u4ee5\u5c31\u9700\u8981\u62c6\u5206\u9879\u76ee\u4e86\u3002<\/p>\n<p>\u8003\u8651\u5230\u5f00\u53d1\u7684\u65b9\u4fbf\u6027\uff0cA\u533a\u4e0eB\u533a\u4e4b\u95f4\u5c31\u5fc5\u987b\u5de5\u4f5c\u5728\u7c7b\u4f3cHessian\u4e4b\u7c7b\u7684\u8fdc\u7a0b\u8c03\u7528\u4e0a\uff0c\u800c\u4e0d\u80fd\u76f4\u63a5\u5728http\u5c42\u4e0a\uff0c\u8981\u4e0d\u7136\u88c5\u5305\u62c6\u5305\u90fd\u7d2f\u6b7b\u4eba\u4e86\u3002<\/p>\n<p>\u9879\u76ee\u76ee\u524d\u7684\u4ee3\u7801\u5c42\u6b21\u662f Rest \u98ce\u683c\u7684 Controller + Service + MyBatis \u7684 Mapper\u3002Controller \u91cc\u5927\u91cf\u4f7f\u7528servlet\u7684API\uff0c\u6240\u4ee5\u4e0d\u80fd\u628acontroller\u5c42\u62bd\u53d6\u51fa\u6765\u4f5c\u4e3a\u8fdc\u7a0b\u8c03\u7528\u7684\u63a5\u53e3\u3002Mapper\u672c\u8eab\u53ea\u662f\u4e00\u4e2a\u63a5\u53e3\uff0cservice\u5c42\u4e0emapper\u5c42\u4e4b\u95f4\u6ca1\u6cd5\u518d\u62c6\uff0c\u53ea\u80fd\u5728controller\u4e0eservice\u4e4b\u95f4\u62c6\u3002\u9879\u76ee\u91cc\u6ca1\u6709\u4e13\u95e8\u4e3a\u6bcf\u4e2a service \u7ec4\u4ef6\u5b9a\u4e49\u4e00\u4e2a\u76f8\u5e94\u7684\u63a5\u53e3\uff0c\u9700\u8981\u6839\u636e\u5df2\u6709\u7684service\u7ec4\u4ef6\u62bd\u53d6\u51fa\u5bf9\u5e94\u7684\u63a5\u53e3\u3002<\/p>\n<p>\u7531\u4e8e\u7ec4\u4ef6\u592a\u591a\uff0c\u53ea\u80fd\u5199\u5de5\u5177\u7c7b\u62bd\u53d6\u3002<\/p>\n<p>\u5de5\u5177\u7c7b\u7684\u76ee\u6807\uff1a<\/p>\n<ol>\n<li>\u62bd\u53d6\u6240\u6709\u7ec4\u4ef6\u7684\u516c\u5f00\u65b9\u6cd5\u4f5c\u4e3a\u63a5\u53e3\u7684\u65b9\u6cd5\uff0c\u4fdd\u7559\u65b9\u6cd5\u5b9a\u4e49\u7684\u7c7b\u578b\u4fe1\u606f\u548c\u53c2\u6570\u540d\u7b49\u4fe1\u606f\u3002<\/li>\n<li>\u751f\u6210\u63a5\u53e3\u6240\u4f9d\u8d56\u7684\u5bfc\u5165\u5e76\u62f7\u8d1d\u6240\u6709\u4f9d\u8d56\u7684\u5bfc\u5165\u7c7b\u3002<\/li>\n<li>\u751f\u6210\u5bf9\u5e94\u7684Hessian\u914d\u7f6e\u3002<\/li>\n<\/ol>\n<p>\u8981\u4fdd\u7559\u65b9\u6cd5\u7684\u53c2\u6570\u540d\u4fe1\u606f\u9700\u8981 Java 8 \u7684\u7279\u6027\u3002Java 8 \u7684 <code>javac<\/code> \u589e\u52a0\u4e86\u4e00\u4e2a\u9009\u9879 <code>-parameters<\/code>\uff0c\u8868\u793a\u5728\u751f\u6210\u7684\u5b57\u8282\u7801\u6587\u4ef6\u91cc\u4fdd\u7559\u65b9\u6cd5\u7684\u53c2\u6570\u540d\u3002<\/p>\n<p><!--more--><\/p>\n<h3>\u5177\u4f53\u6e90\u7801<\/h3>\n<pre><code class=\"java\">package net.coderbee.demo.util;\n\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\n\n\/**\n* \u628a\u6307\u5b9a\u7c7b\u578b\u7684\u516c\u5f00\u65b9\u6cd5\u62bd\u53d6\u51fa\u6765\uff0c\u751f\u6210\u4e00\u4e2a\u540d\u4e3a\uff08\"I\" + \u7c7b\u540d\uff09\u7684\u63a5\u53e3\u7684\u6e90\u7801\uff0c\u5305\u8def\u5f84\u76f8\u540c\uff0c\u5e76\u62f7\u8d1d\u6240\u4f9d\u8d56\u7684\u9879\u76ee\u6e90\u7801\u3002\n* \n* @author coderbee\n*\n*\/\npublic class InterfaceExtractor {\n     \/**\n     * \u8981\u8df3\u8fc7\u7684\u65b9\u6cd5\u540d\n     *\/\n     private final List&lt;String&gt; FILTER_METHOD = Arrays.asList(\"wait\", \"equals\",\n               \"toString\", \"hashCode\", \"getClass\", \"notify\", \"notifyAll\", \"main\");\n\n     \/**\n     * \u4e0d\u9700\u8981\u5bfc\u5165\u7684\u57fa\u672c\u7c7b\u578b\n     *\/\n     private static final List&lt;String&gt; FILTER_TYPE = Arrays.asList(\"boolean\",\n               \"char\", \"byte\", \"int\", \"short\", \"double\", \"float\", \"long\", \"void\");\n\n     private String srcDir; \/\/ \u6e90\u7801\u76ee\u5f55\n     private String dstDir; \/\/ \u751f\u6210\u4ee3\u7801\u7684\u5b58\u653e\u76ee\u5f55\n\n     \/\/ \u4fdd\u5b58\u8981\u5bfc\u5165\u7684\u7c7b\u578b\n     private List&lt;String&gt; imports = new LinkedList&lt;String&gt;();\n\n     \/\/ \u751f\u6210\u7684\u63a5\u53e3\u6e90\u7801\n     private StringBuilder bodyBuilder = new StringBuilder(1024);\n\n     \/**\n     * \n     * @param srcDir\n     *            \u6e90\u7801\u76ee\u5f55\n     * @param dstDir\n     *            \u751f\u6210\u4ee3\u7801\u7684\u5b58\u653e\u76ee\u5f55\n     *\/\n     public InterfaceExtractor(String srcDir, String dstDir) {\n          this.srcDir = srcDir;\n          this.dstDir = dstDir;\n     }\n\n     \/**\n     * \u62bd\u53d6\u6307\u5b9a\u7c7b\u578b\u7684\u63a5\u53e3\n     * \n     * @param claz\n     *            \u8868\u793a\u7c7b\u7684 Class \u5b9e\u4f8b\n     *\/\n     public void extractInterface(@SuppressWarnings(\"rawtypes\") Class claz) {\n          String fullName = getNormalName(claz);\n          String path = getPkgPath(fullName);\n\n          String pkg = \"package \" + path + \";\\n\\n\";\n\n          bodyBuilder.append(\"public interface I\").append(claz.getSimpleName())\n                    .append(\" {\\n\");\n\n          Method[] methods = claz.getMethods();\n          for (Method method : methods) {\n               if (!FILTER_METHOD.contains(method.getName())) {\n                    addMethod(bodyBuilder, method);\n                    bodyBuilder.append('\\n');\n               }\n          }\n\n          bodyBuilder.setCharAt(bodyBuilder.length() - 1, '}');\n\n          writeFileD(dstDir + getIName(fullName) + \".java\", pkg + getImports()\n                    + \"\\n\" + bodyBuilder);\n     }\n\n     private void copyImports(String type) {\n          String subPath = File.separatorChar\n                    + type.replace('.', File.separatorChar) + \".java\";\n\n          File srcFile = new File(srcDir + subPath);\n\n          if (srcFile.exists()) {\n               File dstFile = new File(dstDir + subPath);\n               copy(srcFile, dstFile);\n          }\n     }\n\n     private String getImports() {\n          Collections.sort(imports);\n\n          StringBuilder importBuilder = new StringBuilder(1024);\n          for (String imp : imports) {\n               importBuilder.append(\"import \").append(imp).append(\";\\n\");\n               copyImports(imp);\n          }\n          return importBuilder.toString();\n     }\n\n     \/**\n     * \u6dfb\u52a0\u4e00\u4e2a\u65b9\u6cd5\u7684\u58f0\u660e\n     * \n     * @param sb\n     * @param method\n     *\/\n     private void addMethod(StringBuilder sb, Method method) {\n          bodyBuilder.append('\\t');\n          addReturnType(method);\n\n          bodyBuilder.append(' ').append(method.getName()).append('('); \/\/ \u6dfb\u52a0\u65b9\u6cd5\u540d\n\n          addParameter(method);\n\n          bodyBuilder.append(\");\\n\");\n     }\n\n     \/**\n     * \u6dfb\u52a0\u65b9\u6cd5\u7684\u53c2\u6570\n     * \n     * @param sb\n     * @param method\n     *\/\n     private void addParameter(Method method) {\n          Type[] paramTypeList = method.getGenericParameterTypes();\n          Parameter[] parameters = method.getParameters();\n          for (int i = 0; i &lt; parameters.length; i++) {\n               Type paramType = paramTypeList[i];\n               addTypeParameters(paramType);\n\n               Parameter parameter = parameters[i];\n               bodyBuilder.append(' ').append(parameter.getName());\n               if (i != parameters.length - 1) {\n                    bodyBuilder.append(\", \");\n               }\n          }\n     }\n\n     private String getTypeName(Type type) {\n          if (type instanceof ParameterizedType) {\n               \/\/ \u6cdb\u578b\n               return getGenericTypeName((ParameterizedType) type);\n          } else {\n               \/\/ \u975e\u6cdb\u578b\n               return getSimpleTypeName(type.getTypeName());\n          }\n     }\n\n     private String getGenericTypeName(ParameterizedType type) {\n          Type[] actualTypeArguments = type.getActualTypeArguments();\n          if (actualTypeArguments == null || actualTypeArguments.length == 0) {\n               \/\/ \u6cdb\u578b\u7684\u7c7b\u578b\u975e\u53c2\u6570\u5316\u7684\n               return getSimpleTypeName(type.getTypeName());\n          } else {\n               StringBuilder sb = new StringBuilder(64);\n               String typeName = genericRawType(type.getTypeName());\n               sb.append(getSimpleTypeName(typeName));\n               sb.append('&lt;');\n               for (Type genericType : actualTypeArguments) {\n                    sb.append(getTypeName(genericType)).append(\", \");\n               }\n               sb.setCharAt(sb.length() - 2, '&gt;');\n               return sb.deleteCharAt(sb.length() - 1).toString();\n          }\n     }\n\n     private String genericRawType(String typeName) {\n          int indexOf = typeName.indexOf('&lt;');\n          return typeName.substring(0, indexOf);\n     }\n\n     private String getSimpleTypeName(String typeName) {\n          if (typeName.startsWith(\"[\")) {\n               \/\/ \u8fd4\u56de\u7684\u7c7b\u578b\u662f\u6570\u7ec4\n               return getArrayTypeName(typeName);\n          }\n\n          return getSimpleNameByFullName(typeName);\n     }\n\n     private String getArrayTypeName(String typeName) {\n          \/\/ \u7b2c\u4e8c\u4e2a\u5b57\u7b26\u8868\u793a\u6570\u7ec4\u5143\u7d20\u7684\u7c7b\u578b\n          char ch = typeName.charAt(1);\n          if (ch == 'Z') {\n               return \"boolean[]\";\n          } else if (ch == 'B') {\n               return \"byte[]\";\n          } else if (ch == 'C') {\n               return \"char[]\";\n          } else if (ch == 'S') {\n               return \"short[]\";\n          } else if (ch == 'I') {\n               return \"int[]\";\n          } else if (ch == 'F') {\n               return \"float[]\";\n          } else if (ch == 'D') {\n               return \"double[]\";\n          } else if (ch == 'J') {\n               return \"long[]\";\n          } else if (ch == 'L') {\n               \/\/ \u5bf9\u8c61\u6570\u7ec4\n               String tName = typeName.substring(2, typeName.indexOf(';'));\n               return getSimpleNameByFullName(tName) + \"[]\";\n          } else {\n               return \"\";\n          }\n     }\n\n     \/**\n     * \u901a\u8fc7\u7c7b\u5b8c\u6574\u8def\u5f84\u540d\u83b7\u53d6\u7c7b\u7684\u7b80\u5355\u540d\u5b57\uff0c\u5e76\u52a0\u5165\u5bfc\u5165\u5217\u8868\u3002\n     * \n     * @param fullName\n     *            \u7c7b\u5b8c\u6574\u8def\u5f84\u540d\n     * @return \u7b80\u5355\u540d\u5b57\n     *\/\n     private String getSimpleNameByFullName(String fullName) {\n          String[] split = fullName.split(\"\\\\.\");\n          if (split.length == 3 &amp;&amp; fullName.startsWith(\"java.lang.\")) {\n               \/\/ java.lang \u5305\u4e0b\u7684\u4e0d\u9700\u8981\u663e\u5f0f import\n               return split[2];\n          } else {\n               if (!FILTER_TYPE.contains(fullName) &amp;&amp; fullName.length() &gt; 1\n                         &amp;&amp; !imports.contains(fullName) &amp;&amp; !fullName.contains(\"[\")) {\n                    \/\/ \u8fc7\u6ee4\u6570\u7ec4\u53c2\u6570\u7c7b\u578b\uff08\u5982\uff1aint[] \uff09\n                    imports.add(fullName);\n               }\n               return split[split.length - 1];\n          }\n     }\n\n     \/**\n     * \u6dfb\u52a0\u65b9\u6cd5\u7684\u8fd4\u56de\u7c7b\u578b\n     * \n     * @param sb\n     * @param method\n     *\/\n     private void addReturnType(Method method) {\n          if (method.getName().endsWith(\"getDeuAmoArr\")) {\n               System.out.println(\"hold\");\n          }\n          Type genericReturnType = method.getGenericReturnType();\n          if (genericReturnType instanceof ParameterizedType) {\n               \/\/ \u6cdb\u578b\n               String typeName = getGenericTypeName((ParameterizedType) genericReturnType);\n               bodyBuilder.append(typeName);\n          } else {\n               \/\/ \u975e\u6cdb\u578b\n               Class&lt;?&gt; returnType = method.getReturnType();\n               String returnTypeName = getSimpleTypeName(returnType.getName());\n               bodyBuilder.append(returnTypeName);\n          }\n     }\n\n     \/**\n     * \u6dfb\u52a0\u6cdb\u578b\u7684\u5b9e\u9645\u7c7b\u578b\n     * \n     * @param sb\n     * @param type\n     *            \u8fd4\u56de\u7c7b\u578b\u6216\u65b9\u6cd5\u53c2\u6570\u7684\u7c7b\u578b\n     *\/\n     private void addTypeParameters(Type type) {\n          String typeName = type.getTypeName();\n          if (type instanceof ParameterizedType) {\n               bodyBuilder.append(getGenericTypeName((ParameterizedType) type));\n          } else {\n               String[] split = typeName.split(\" \", 2);\n               if (split.length &gt; 1) {\n                    bodyBuilder.append(split[1]);\n               } else {\n                    bodyBuilder.append(getSimpleTypeName(typeName));\n               }\n          }\n     }\n\n     \/**\n     * \u83b7\u53d6 \u5305 \u8def\u5f84\n     * \n     * @param fullName\n     * @return\n     *\/\n     private String getPkgPath(String fullName) {\n          int i = fullName.lastIndexOf('.');\n          return fullName.substring(0, i);\n     }\n\n     \/**\n     * \u83b7\u53d6\u4ee3\u7801\u6240\u58f0\u660e\u7684\u7c7b\u7684\u5b8c\u6574\u8def\u5f84\u540d\n     * \n     * @param claz\n     * @return\n     *\/\n     private String getNormalName(@SuppressWarnings(\"rawtypes\") Class claz) {\n          String name = claz.getName();\n\n          int i = name.indexOf('$');\n          if (i != -1) {\n               name = name.substring(0, i);\n          }\n\n          return name;\n     }\n\n     private static String getIName(String fullName) {\n          String[] split = fullName.split(\"\\\\.\");\n\n          StringBuilder sb = new StringBuilder(fullName.length());\n          for (int i = 0; i &lt; split.length - 1; i++) {\n               sb.append(split[i]).append(File.separatorChar);\n          }\n          sb.append('I').append(split[split.length - 1]);\n\n          return sb.toString();\n     }\n\n     public static void writeFileD(String fullPath, String body) {\n          FileOutputStream fout = null;\n          try {\n               File file = new File(fullPath);\n               if (!file.getParentFile().exists()) {\n                    file.getParentFile().mkdirs();\n               }\n               fout = new FileOutputStream(file);\n               fout.write(body.getBytes(\"UTF-8\"));\n\n          } catch (IOException e) {\n               e.printStackTrace();\n          } finally {\n               closeQuietly(fout);\n          }\n     }\n\n     private void copy(File srcFile, File dstFile) {\n          File dstDir = dstFile.getParentFile();\n          if (!dstDir.exists()) {\n               dstDir.mkdirs();\n          }\n\n          FileInputStream inputStream = null;\n          FileOutputStream outputStream = null;\n          try {\n               inputStream = new FileInputStream(srcFile);\n               outputStream = new FileOutputStream(dstFile);\n\n               inputStream.getChannel().transferTo(0, srcFile.length(),\n                         outputStream.getChannel());\n          } catch (FileNotFoundException e) {\n               e.printStackTrace();\n          } catch (IOException e) {\n               e.printStackTrace();\n          } finally {\n               closeQuietly(inputStream);\n               closeQuietly(outputStream);\n          }\n     }\n\n     public static void closeQuietly(Closeable closeable) {\n          if (closeable != null) {\n               try {\n                    closeable.close();\n               } catch (IOException ignored) {\n               }\n          }\n     }\n}\n<\/code><\/pre>\n<hr\/>\n<p>\u6b22\u8fce\u5173\u6ce8\u6211\u7684\u5fae\u4fe1\u516c\u4f17\u53f7: <strong>coderbee\u7b14\u8bb0<\/strong>\uff0c\u53ef\u4ee5\u66f4\u53ca\u65f6\u56de\u590d\u4f60\u7684\u8ba8\u8bba\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"258\" height=\"258\" src=\"https:\/\/coderbee.net\/wp-content\/uploads\/2019\/01\/coderbee-note.jpg\" class=\"alignnone size-full wp-image-1707\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u76ee\u524d\u53c2\u4e0e\u7684\u9879\u76ee\u662f\u7528 Spring MVC + MyBatis \u5b9e\u73b0\u7684\uff0c\u9879\u76ee\u90e8\u7f72\u5c31 &hellip; <a href=\"https:\/\/coderbee.net\/index.php\/java\/20141122\/1078\">\u7ee7\u7eed\u9605\u8bfb <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[204,203],"_links":{"self":[{"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/posts\/1078"}],"collection":[{"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/comments?post=1078"}],"version-history":[{"count":3,"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/posts\/1078\/revisions"}],"predecessor-version":[{"id":1081,"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/posts\/1078\/revisions\/1081"}],"wp:attachment":[{"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/media?parent=1078"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/categories?post=1078"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderbee.net\/index.php\/wp-json\/wp\/v2\/tags?post=1078"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}