You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/01/10 11:03:43 UTC

[dubbo] branch 3.0 updated: [Dubbo-7029] new format ServiceDefinition (#7029)

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 7580232  [Dubbo-7029] new format ServiceDefinition (#7029)
7580232 is described below

commit 7580232b4a1f2a487965ba2b9ba6594e1f5e3a46
Author: Robert LU <ro...@gmail.com>
AuthorDate: Sun Jan 10 19:02:52 2021 +0800

    [Dubbo-7029] new format ServiceDefinition (#7029)
---
 .../java/org/apache/dubbo/event/EventListener.java |  1 +
 .../apache/dubbo/common/lang/PrioritizedTest.java  |  1 +
 .../dubbo/common/utils/DefaultCharSequence.java    |  1 +
 .../apache/dubbo/generic/GenericServiceTest.java   | 42 ++++++------
 .../metadata/definition/TypeDefinitionBuilder.java | 17 +++--
 .../definition/builder/ArrayTypeBuilder.java       | 18 ++++--
 .../definition/builder/CollectionTypeBuilder.java  | 23 +++++--
 .../definition/builder/DefaultTypeBuilder.java     | 21 +++---
 .../definition/builder/EnumTypeBuilder.java        | 22 +++++--
 .../definition/builder/MapTypeBuilder.java         | 22 +++++--
 .../metadata/definition/builder/TypeBuilder.java   |  2 +-
 .../definition/model/MethodDefinition.java         | 13 ++--
 .../definition/model/ServiceDefinition.java        | 18 ++++++
 .../metadata/definition/model/TypeDefinition.java  | 74 ++++++++++------------
 .../dubbo/metadata/definition/util/ClassUtils.java | 55 ++++++++++++++++
 .../rest/jaxrs/DefaultValueParameterProcessor.java |  1 +
 .../dubbo/metadata/definition/MetadataTest.java    | 18 ++----
 .../definition/ServiceDefinitionBuilderTest.java   | 40 ++++++------
 .../metadata/definition/Test3TypeBuilder.java      |  3 +-
 .../dubbo/metadata/definition/TestTypeBuilder.java |  3 +-
 .../definition/protobuf/ProtobufTypeBuilder.java   | 56 +++++++++-------
 .../protobuf/ProtobufTypeBuilderTest.java          | 41 ++++++++----
 .../builder/ArrayTypeDefinitionBuilder.java        | 13 ++--
 .../builder/CollectionTypeDefinitionBuilder.java   | 11 +++-
 .../builder/DeclaredTypeDefinitionBuilder.java     |  4 +-
 .../builder/EnumTypeDefinitionBuilder.java         |  8 ++-
 .../builder/GeneralTypeDefinitionBuilder.java      | 17 +++--
 .../builder/MapTypeDefinitionBuilder.java          | 10 +--
 .../builder/MethodDefinitionBuilder.java           |  9 +--
 .../builder/PrimitiveTypeDefinitionBuilder.java    | 11 ++--
 .../builder/ServiceDefinitionBuilder.java          | 15 +++--
 .../builder/SimpleTypeDefinitionBuilder.java       |  9 ++-
 .../annotation/processing/builder/TypeBuilder.java | 31 +++++++++
 .../processing/builder/TypeDefinitionBuilder.java  | 43 ++++---------
 .../rest/AbstractServiceRestMetadataResolver.java  |  2 +-
 .../rest/jaxrs/DefaultValueParameterProcessor.java |  1 +
 ...data.annotation.processing.builder.TypeBuilder} |  0
 .../builder/ArrayTypeDefinitionBuilderTest.java    | 10 ++-
 .../builder/EnumTypeDefinitionBuilderTest.java     |  6 +-
 .../builder/MapTypeDefinitionBuilderTest.java      | 23 ++++---
 .../PrimitiveTypeDefinitionBuilderTest.java        | 10 +--
 .../builder/ServiceDefinitionBuilderTest.java      | 35 +++++++---
 42 files changed, 486 insertions(+), 274 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java b/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java
index bb36c77..4ca275d 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java
@@ -55,6 +55,7 @@ public interface EventListener<E extends Event> extends java.util.EventListener,
      * {@link Integer#MIN_VALUE} indicates the highest priority. The default value is {@link Integer#MAX_VALUE}.
      * The comparison rule , refer to {@link #compareTo}.
      */
+    @Override
     default int getPriority() {
         return NORMAL_PRIORITY;
     }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/lang/PrioritizedTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/lang/PrioritizedTest.java
index 5311ced..87d28dc 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/lang/PrioritizedTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/lang/PrioritizedTest.java
@@ -100,6 +100,7 @@ public class PrioritizedTest {
             this.value = value;
         }
 
+        @Override
         public int getPriority() {
             return value;
         }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/DefaultCharSequence.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/DefaultCharSequence.java
index 0db1c96..9ceb00a 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/DefaultCharSequence.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/DefaultCharSequence.java
@@ -39,6 +39,7 @@ public class DefaultCharSequence implements CharSequence, Prioritized {
         return null;
     }
 
+    @Override
     public int getPriority() {
         return MAX_PRIORITY;
     }
diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java
index ec9a08e..fba3c40 100644
--- a/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java
+++ b/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java
@@ -106,7 +106,7 @@ public class GenericServiceTest {
 
         FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(DemoService.class);
         MethodDefinition methodDefinition = getMethod("complexCompute", fullServiceDefinition.getMethods());
-        Map mapObject = createComplexObject(fullServiceDefinition,var1, var2, l, var3, var4, testEnum);
+        Map mapObject = createComplexObject(fullServiceDefinition, var1, var2, l, var3, var4, testEnum);
         ComplexObject complexObject = map2bean(mapObject);
 
         Invoker<GenericService> invoker = protocol.refer(GenericService.class, url);
@@ -172,32 +172,32 @@ public class GenericServiceTest {
         TypeDefinition inner2TypeDefinition = null;
         TypeDefinition inner3TypeDefinition = null;
         for (TypeDefinition typeDefinition : typeDefinitions) {
-            if (typeDefinition.getType().equals(ComplexObject.class.getName())) {
+            if (typeDefinition.getType().equals(ComplexObject.class.getCanonicalName())) {
                 topTypeDefinition = typeDefinition;
-            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getName())) {
+            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getCanonicalName())) {
                 innerTypeDefinition = typeDefinition;
-            } else if (typeDefinition.getType().contains(ComplexObject.InnerObject2.class.getName())) {
+            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject2.class.getCanonicalName())) {
                 inner2TypeDefinition = typeDefinition;
-            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getName())) {
+            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getCanonicalName())) {
                 inner3TypeDefinition = typeDefinition;
             }
         }
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("v").getType(), "long");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("maps").getType(), "java.util.Map<java.lang.String,java.lang.String>");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject").getType(), "org.apache.dubbo.service.ComplexObject$InnerObject");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("intList").getType(), "java.util.List<java.lang.Integer>");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("strArrays").getType(), "java.lang.String[]");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject3").getType(), "org.apache.dubbo.service.ComplexObject.InnerObject3[]");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("testEnum").getType(), "org.apache.dubbo.service.ComplexObject.TestEnum");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject2").getType(), "java.util.List<org.apache.dubbo.service.ComplexObject$InnerObject2>");
-
-        Assertions.assertSame(innerTypeDefinition.getProperties().get("innerA").getType(), "java.lang.String");
-        Assertions.assertSame(innerTypeDefinition.getProperties().get("innerB").getType(), "int");
-
-        Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerA2").getType(), "java.lang.String");
-        Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerB2").getType(), "int");
-
-        Assertions.assertSame(inner3TypeDefinition.getProperties().get("innerA3").getType(), "java.lang.String");
+        Assertions.assertEquals("long", topTypeDefinition.getProperties().get("v"));
+        Assertions.assertEquals("java.util.Map<java.lang.String,java.lang.String>", topTypeDefinition.getProperties().get("maps"));
+        Assertions.assertEquals("org.apache.dubbo.service.ComplexObject.InnerObject", topTypeDefinition.getProperties().get("innerObject"));
+        Assertions.assertEquals("java.util.List<java.lang.Integer>", topTypeDefinition.getProperties().get("intList"));
+        Assertions.assertEquals("java.lang.String[]", topTypeDefinition.getProperties().get("strArrays"));
+        Assertions.assertEquals("org.apache.dubbo.service.ComplexObject.InnerObject3[]", topTypeDefinition.getProperties().get("innerObject3"));
+        Assertions.assertEquals("org.apache.dubbo.service.ComplexObject.TestEnum", topTypeDefinition.getProperties().get("testEnum"));
+        Assertions.assertEquals("java.util.List<org.apache.dubbo.service.ComplexObject.InnerObject2>", topTypeDefinition.getProperties().get("innerObject2"));
+
+        Assertions.assertSame("java.lang.String", innerTypeDefinition.getProperties().get("innerA"));
+        Assertions.assertSame("int", innerTypeDefinition.getProperties().get("innerB"));
+
+        Assertions.assertSame("java.lang.String", inner2TypeDefinition.getProperties().get("innerA2"));
+        Assertions.assertSame("int", inner2TypeDefinition.getProperties().get("innerB2"));
+
+        Assertions.assertSame("java.lang.String", inner3TypeDefinition.getProperties().get("innerA3"));
 
         Map<String, Object> result = new HashMap<>();
         result.put("v", l);
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
index fe99d2e..25cea86 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
@@ -19,6 +19,7 @@ package org.apache.dubbo.metadata.definition;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.ClassUtils;
 import org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder;
 import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
@@ -30,7 +31,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static org.apache.dubbo.common.utils.ClassUtils.isSimpleType;
 
 /**
  * 2015/1/27.
@@ -45,18 +45,17 @@ public class TypeDefinitionBuilder {
         BUILDERS = new ArrayList<>(tbs);
     }
 
-    public static TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
+    public static TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
         TypeBuilder builder = getGenericTypeBuilder(type, clazz);
         TypeDefinition td;
-        if (builder != null) {
+
+        if (clazz.isPrimitive() || ClassUtils.isSimpleType(clazz)) { // changed since 2.7.6
+            td = new TypeDefinition(clazz.getCanonicalName());
+            typeCache.put(clazz.getCanonicalName(), td);
+        } else if (builder != null) {
             td = builder.build(type, clazz, typeCache);
-            td.setTypeBuilderName(builder.getClass().getName());
         } else {
             td = DefaultTypeBuilder.build(clazz, typeCache);
-            td.setTypeBuilderName(DefaultTypeBuilder.class.getName());
-        }
-        if (isSimpleType(clazz)) { // changed since 2.7.6
-            td.setProperties(null);
         }
         return td;
     }
@@ -75,7 +74,7 @@ public class TypeDefinitionBuilder {
         return null;
     }
 
-    private Map<Class<?>, TypeDefinition> typeCache = new HashMap<>();
+    private Map<String, TypeDefinition> typeCache = new HashMap<>();
 
     public TypeDefinition build(Type type, Class<?> clazz) {
         return build(type, clazz, typeCache);
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
index 9ad61ce..e5191a1 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
@@ -36,13 +36,21 @@ public class ArrayTypeBuilder implements TypeBuilder {
     }
 
     @Override
-    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
+        final String canonicalName = clazz.getCanonicalName();
+        TypeDefinition td = typeCache.get(canonicalName);
+        if (td != null) {
+            return td;
+        }
+        td = new TypeDefinition(canonicalName);
+        typeCache.put(canonicalName, td);
         // Process the component type of an array.
         Class<?> componentType = clazz.getComponentType();
-        TypeDefinitionBuilder.build(componentType, componentType, typeCache);
-
-        final String canonicalName = clazz.getCanonicalName();
-        return new TypeDefinition(canonicalName);
+        TypeDefinition itemTd = TypeDefinitionBuilder.build(componentType, componentType, typeCache);
+        if (itemTd != null) {
+            td.getItems().add(itemTd.getType());
+        }
+        return td;
     }
 
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
index 1e74684..4e28e65 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.metadata.definition.builder;
 
 import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+import org.apache.dubbo.metadata.definition.util.ClassUtils;
 
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -40,9 +41,9 @@ public class CollectionTypeBuilder implements TypeBuilder {
     }
 
     @Override
-    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
         if (!(type instanceof ParameterizedType)) {
-            return new TypeDefinition(clazz.getName());
+            return new TypeDefinition(clazz.getCanonicalName());
         }
 
         ParameterizedType parameterizedType = (ParameterizedType) type;
@@ -54,17 +55,29 @@ public class CollectionTypeBuilder implements TypeBuilder {
                     type, actualTypeArgs));
         }
 
+        String colType = ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
+        TypeDefinition td = typeCache.get(colType);
+        if (td != null) {
+            return td;
+        }
+        td = new TypeDefinition(colType);
+        typeCache.put(colType, td);
+
         Type actualType = actualTypeArgs[0];
+        TypeDefinition itemTd = null;
         if (actualType instanceof ParameterizedType) {
             // Nested collection or map.
             Class<?> rawType = (Class<?>) ((ParameterizedType) actualType).getRawType();
-            TypeDefinitionBuilder.build(actualType, rawType, typeCache);
+            itemTd = TypeDefinitionBuilder.build(actualType, rawType, typeCache);
         } else if (actualType instanceof Class<?>) {
             Class<?> actualClass = (Class<?>) actualType;
-            TypeDefinitionBuilder.build(null, actualClass, typeCache);
+            itemTd = TypeDefinitionBuilder.build(null, actualClass, typeCache);
+        }
+        if (itemTd != null) {
+            td.getItems().add(itemTd.getType());
         }
 
-        return new TypeDefinition(type.toString());
+        return td;
     }
 
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
index 567b4b3..4ac52a4 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
@@ -31,15 +31,16 @@ import java.util.Map;
  */
 public final class DefaultTypeBuilder {
 
-    public static TypeDefinition build(Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
-//        final String canonicalName = clazz.getCanonicalName();
-        final String name = clazz.getName();
+    public static TypeDefinition build(Class<?> clazz, Map<String, TypeDefinition> typeCache) {
+        final String canonicalName = clazz.getCanonicalName();
 
-        TypeDefinition td = new TypeDefinition(name);
         // Try to get a cached definition
-        if (typeCache.containsKey(clazz)) {
-            return typeCache.get(clazz);
+        TypeDefinition td = typeCache.get(canonicalName);
+        if (td != null) {
+            return td;
         }
+        td = new TypeDefinition(canonicalName);
+        typeCache.put(canonicalName, td);
 
         // Primitive type
         if (!JaketConfigurationUtils.needAnalyzing(clazz)) {
@@ -47,21 +48,15 @@ public final class DefaultTypeBuilder {
         }
 
         // Custom type
-        TypeDefinition ref = new TypeDefinition(name);
-        ref.set$ref(name);
-        typeCache.put(clazz, ref);
-
         List<Field> fields = ClassUtils.getNonStaticFields(clazz);
         for (Field field : fields) {
             String fieldName = field.getName();
             Class<?> fieldClass = field.getType();
             Type fieldType = field.getGenericType();
-
             TypeDefinition fieldTd = TypeDefinitionBuilder.build(fieldType, fieldClass, typeCache);
-            td.getProperties().put(fieldName, fieldTd);
+            td.getProperties().put(fieldName, fieldTd.getType());
         }
 
-        typeCache.put(clazz, td);
         return td;
     }
 
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
index 03953eb..1c5c3ed 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.metadata.definition.builder;
 
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 
 import java.lang.reflect.Method;
@@ -26,6 +29,7 @@ import java.util.Map;
  * 2015/1/27.
  */
 public class EnumTypeBuilder implements TypeBuilder {
+    private static final Logger logger = LoggerFactory.getLogger(TypeDefinitionBuilder.class);
 
     @Override
     public boolean accept(Type type, Class<?> clazz) {
@@ -36,8 +40,15 @@ public class EnumTypeBuilder implements TypeBuilder {
     }
 
     @Override
-    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
-        TypeDefinition td = new TypeDefinition(clazz.getCanonicalName());
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
+        String canonicalName = clazz.getCanonicalName();
+
+        TypeDefinition td = typeCache.get(canonicalName);
+        if (td != null) {
+            return td;
+        }
+        td = new TypeDefinition(canonicalName);
+        typeCache.put(canonicalName, td);
 
         try {
             Method methodValues = clazz.getDeclaredMethod("values");
@@ -47,12 +58,11 @@ public class EnumTypeBuilder implements TypeBuilder {
                 Object value = values[i];
                 td.getEnums().add(value.toString());
             }
+            return td;
         } catch (Throwable t) {
-            td.setId("-1");
+            logger.error("There is an error while process class " + clazz, t);
         }
-
-        typeCache.put(clazz, td);
-        return td;
+        return null;
     }
 
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
index 4fd3865..cda2e58 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.metadata.definition.builder;
 
 import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+import org.apache.dubbo.metadata.definition.util.ClassUtils;
 
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -44,9 +45,9 @@ public class MapTypeBuilder implements TypeBuilder {
     }
 
     @Override
-    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
         if (!(type instanceof ParameterizedType)) {
-            return new TypeDefinition(clazz.getName());
+            return new TypeDefinition(clazz.getCanonicalName());
         }
 
         ParameterizedType parameterizedType = (ParameterizedType) type;
@@ -65,9 +66,15 @@ public class MapTypeBuilder implements TypeBuilder {
          * {@link ParameterizedType#toString()}
          * @see sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
          */
-        String mapType = replace(type.toString(), ", ", ",");
+        String mapType = ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
+        mapType = replace(mapType, ", ", ",");
 
-        TypeDefinition typeDefinition = new TypeDefinition(mapType);
+        TypeDefinition td = typeCache.get(mapType);
+        if (td != null) {
+            return td;
+        }
+        td = new TypeDefinition(mapType);
+        typeCache.put(mapType, td);
 
         for (int i = 0; i < actualTypeArgsLength; i++) {
             Type actualType = actualTypeArgs[i];
@@ -79,9 +86,10 @@ public class MapTypeBuilder implements TypeBuilder {
             } else if (isClass(actualType)) {
                 item = TypeDefinitionBuilder.build(null, rawType, typeCache);
             }
-            typeDefinition.getItems().add(item);
+            if (item != null) {
+                td.getItems().add(item.getType());
+            }
         }
-
-        return typeDefinition;
+        return td;
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
index 57673fe..0bd48d3 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
@@ -37,6 +37,6 @@ public interface TypeBuilder extends Prioritized {
     /**
      * Build type definition with the type or class.
      */
-    TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache);
+    TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache);
 
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
index 3635621..906eef7 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
@@ -30,6 +30,12 @@ public class MethodDefinition implements Serializable {
     private String name;
     private String[] parameterTypes;
     private String returnType;
+
+    /**
+     * @deprecated please use parameterTypes,
+     * and find TypeDefinition in org.apache.dubbo.metadata.definition.model.ServiceDefinition#types
+     */
+    @Deprecated
     private List<TypeDefinition> parameters;
 
     public String getName() {
@@ -84,14 +90,11 @@ public class MethodDefinition implements Serializable {
         MethodDefinition that = (MethodDefinition) o;
         return Objects.equals(getName(), that.getName()) &&
                 Arrays.equals(getParameterTypes(), that.getParameterTypes()) &&
-                Objects.equals(getReturnType(), that.getReturnType()) &&
-                Objects.equals(getParameters(), that.getParameters());
+                Objects.equals(getReturnType(), that.getReturnType());
     }
 
     @Override
     public int hashCode() {
-        int result = Objects.hash(getName(), getReturnType(), getParameters());
-        result = 31 * result + Arrays.hashCode(getParameterTypes());
-        return result;
+        return Objects.hash(getName(), getReturnType(), getParameterTypes());
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
index 8b202df..ed7d03b 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
@@ -16,6 +16,8 @@
  */
 package org.apache.dubbo.metadata.definition.model;
 
+import org.apache.dubbo.metadata.definition.util.ClassUtils;
+
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
@@ -26,9 +28,25 @@ import java.util.Objects;
  */
 public class ServiceDefinition implements Serializable {
 
+    /**
+     * the canonical name of interface
+     *
+     * @see Class#getCanonicalName()
+     */
     private String canonicalName;
+
+    /**
+     * the location of class file
+     *
+     * @see ClassUtils#getCodeSource(Class)
+     */
     private String codeSource;
+
     private List<MethodDefinition> methods;
+
+    /**
+     * the definitions of type
+     */
     private List<TypeDefinition> types;
 
     public String getCanonicalName() {
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
index c5e7243..c5f0831 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
@@ -19,6 +19,8 @@ package org.apache.dubbo.metadata.definition.model;
 import com.google.gson.annotations.SerializedName;
 
 import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -30,15 +32,35 @@ import java.util.Objects;
  */
 public class TypeDefinition implements Serializable {
 
-    private String id;
+    /**
+     * the name of type
+     *
+     * @see Class#getCanonicalName()
+     * @see org.apache.dubbo.metadata.definition.util.ClassUtils#getCanonicalNameForParameterizedType(ParameterizedType) 
+     */
     private String type;
+
+    /**
+     * the items(generic parameter) of Map/List(ParameterizedType)
+     * <p>
+     * if this type is not ParameterizedType, the items is null or empty
+     */
     @SerializedName("items")
-    private List<TypeDefinition> items;
+    private List<String> items;
+
+    /**
+     * the enum's value
+     * <p>
+     * If this type is not enum, enums is null or empty
+     */
     @SerializedName("enum")
     private List<String> enums;
-    private String $ref;
-    private Map<String, TypeDefinition> properties;
-    private String typeBuilderName;
+
+    /**
+     * the key is property name,
+     * the value is property's type name
+     */
+    private Map<String, String> properties;
 
     public TypeDefinition() {
     }
@@ -47,29 +69,21 @@ public class TypeDefinition implements Serializable {
         this.type = type;
     }
 
-    public String get$ref() {
-        return $ref;
-    }
-
     public List<String> getEnums() {
         if (enums == null) {
-            enums = new ArrayList<String>();
+            enums = new ArrayList<>();
         }
         return enums;
     }
 
-    public String getId() {
-        return id;
-    }
-
-    public List<TypeDefinition> getItems() {
+    public List<String> getItems() {
         if (items == null) {
             items = new ArrayList<>();
         }
         return items;
     }
 
-    public Map<String, TypeDefinition> getProperties() {
+    public Map<String, String> getProperties() {
         if (properties == null) {
             properties = new HashMap<>();
         }
@@ -80,27 +94,15 @@ public class TypeDefinition implements Serializable {
         return type;
     }
 
-    public String getTypeBuilderName() {
-        return typeBuilderName;
-    }
-
-    public void set$ref(String $ref) {
-        this.$ref = $ref;
-    }
-
     public void setEnums(List<String> enums) {
         this.enums = enums;
     }
 
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public void setItems(List<TypeDefinition> items) {
+    public void setItems(List<String> items) {
         this.items = items;
     }
 
-    public void setProperties(Map<String, TypeDefinition> properties) {
+    public void setProperties(Map<String, String> properties) {
         this.properties = properties;
     }
 
@@ -108,13 +110,9 @@ public class TypeDefinition implements Serializable {
         this.type = type;
     }
 
-    public void setTypeBuilderName(String typeBuilderName) {
-        this.typeBuilderName = typeBuilderName;
-    }
-
     @Override
     public String toString() {
-        return "TypeDefinition [id=" + id + ", type=" + type + ", properties=" + properties + ", $ref=" + $ref + "]";
+        return "TypeDefinition [type=" + type + ", properties=" + properties + "]";
     }
 
     @Override
@@ -126,16 +124,14 @@ public class TypeDefinition implements Serializable {
             return false;
         }
         TypeDefinition that = (TypeDefinition) o;
-        return Objects.equals(getId(), that.getId()) &&
-                Objects.equals(getType(), that.getType()) &&
+        return Objects.equals(getType(), that.getType()) &&
                 Objects.equals(getItems(), that.getItems()) &&
                 Objects.equals(getEnums(), that.getEnums()) &&
-                Objects.equals(get$ref(), that.get$ref()) &&
                 Objects.equals(getProperties(), that.getProperties());
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(getId(), getType(), getItems(), getEnums(), get$ref(), getProperties());
+        return Objects.hash(getType(), getItems(), getEnums(), getProperties());
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
index 7c7eacb..ffa7e2c 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
@@ -16,9 +16,13 @@
  */
 package org.apache.dubbo.metadata.definition.util;
 
+import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.net.URL;
 import java.security.CodeSource;
 import java.security.ProtectionDomain;
@@ -106,6 +110,57 @@ public final class ClassUtils {
         return result;
     }
 
+    public static String getCanonicalNameForParameterizedType(ParameterizedType parameterizedType) {
+        StringBuilder sb = new StringBuilder();
+        Type ownerType = parameterizedType.getOwnerType();
+        Class<?> rawType = (Class) parameterizedType.getRawType();
+        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+
+        if (ownerType != null) {
+            if (ownerType instanceof Class) {
+                sb.append(((Class) ownerType).getName());
+            } else {
+                sb.append(ownerType.toString());
+            }
+
+            sb.append(".");
+
+            if (ownerType instanceof ParameterizedTypeImpl) {
+                // Find simple name of nested type by removing the
+                // shared prefix with owner.
+                sb.append(rawType.getName().replace(((Class) ((ParameterizedType) ownerType).getRawType()).getName() + "$",
+                        ""));
+            } else {
+                sb.append(rawType.getSimpleName());
+            }
+        } else {
+            sb.append(rawType.getCanonicalName());
+        }
+
+        if (actualTypeArguments != null &&
+                actualTypeArguments.length > 0) {
+            sb.append("<");
+            boolean first = true;
+            for (Type t : actualTypeArguments) {
+                if (!first) {
+                    sb.append(", ");
+                }
+                if (t instanceof Class) {
+                    Class c = (Class) t;
+                    sb.append(c.getCanonicalName());
+                } else if (t instanceof ParameterizedType) {
+                    sb.append(getCanonicalNameForParameterizedType((ParameterizedType) t));
+                } else {
+                    sb.append(t.toString());
+                }
+                first = false;
+            }
+            sb.append(">");
+        }
+
+        return sb.toString();
+    }
+
     private ClassUtils() {
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java
index a9e7c0e..a3bfe8d 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java
@@ -68,6 +68,7 @@ public class DefaultValueParameterProcessor extends AbstractAnnotatedMethodParam
         }
     }
 
+    @Override
     public int getPriority() {
         return MIN_PRIORITY;
     }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
index 5a921f8..a75be44 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
@@ -16,10 +16,6 @@
  */
 package org.apache.dubbo.metadata.definition;
 
-import org.apache.dubbo.metadata.definition.builder.CollectionTypeBuilder;
-import org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder;
-import org.apache.dubbo.metadata.definition.builder.EnumTypeBuilder;
-import org.apache.dubbo.metadata.definition.builder.MapTypeBuilder;
 import org.apache.dubbo.metadata.definition.common.ClassExtendsMap;
 import org.apache.dubbo.metadata.definition.common.ColorEnum;
 import org.apache.dubbo.metadata.definition.common.OuterClass;
@@ -40,6 +36,7 @@ import org.junit.jupiter.api.Test;
 public class MetadataTest {
 
     /**
+     *
      */
     @Test
     public void testInnerClassType() {
@@ -47,10 +44,9 @@ public class MetadataTest {
         TypeDefinition td = builder.build(OuterClass.InnerClass.class, OuterClass.InnerClass.class);
         System.out.println(">> testInnerClassType: " + new Gson().toJson(td));
 
-        Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.OuterClass$InnerClass", td.getType());
+        Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.OuterClass.InnerClass", td.getType());
         Assertions.assertEquals(1, td.getProperties().size());
         Assertions.assertNotNull(td.getProperties().get("name"));
-        Assertions.assertEquals(DefaultTypeBuilder.class.getName(), td.getTypeBuilderName());
         ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
         System.out.println(">> testInnerClassType: " + new Gson().toJson(sd));
 
@@ -58,7 +54,7 @@ public class MetadataTest {
         Assertions.assertEquals(TestService.class.getMethods().length, sd.getMethods().size());
         boolean containsType = false;
         for (TypeDefinition type : sd.getTypes()) {
-            if (type.getType().equals("org.apache.dubbo.metadata.definition.common.OuterClass$InnerClass")) {
+            if (type.getType().equals("org.apache.dubbo.metadata.definition.common.OuterClass.InnerClass")) {
                 containsType = true;
                 break;
             }
@@ -76,10 +72,8 @@ public class MetadataTest {
 
         Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ResultWithRawCollections", td.getType());
         Assertions.assertEquals(2, td.getProperties().size());
-        Assertions.assertEquals("java.util.Map", td.getProperties().get("map").getType());
-        Assertions.assertEquals(MapTypeBuilder.class.getName(), td.getProperties().get("map").getTypeBuilderName());
-        Assertions.assertEquals("java.util.List", td.getProperties().get("list").getType());
-        Assertions.assertEquals(CollectionTypeBuilder.class.getName(), td.getProperties().get("list").getTypeBuilderName());
+        Assertions.assertEquals("java.util.Map", td.getProperties().get("map"));
+        Assertions.assertEquals("java.util.List", td.getProperties().get("list"));
 
         ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
         System.out.println(">> testRawMap: " + new Gson().toJson(sd));
@@ -103,7 +97,6 @@ public class MetadataTest {
         System.out.println(">> testEnum: " + new Gson().toJson(td));
 
         Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ColorEnum", td.getType());
-        Assertions.assertEquals(EnumTypeBuilder.class.getName(), td.getTypeBuilderName());
         Assertions.assertEquals(3, td.getEnums().size());
         Assertions.assertTrue(td.getEnums().contains("RED"));
         Assertions.assertTrue(td.getEnums().contains("YELLOW"));
@@ -131,7 +124,6 @@ public class MetadataTest {
         System.out.println(">> testExtendsMap: " + new Gson().toJson(td));
 
         Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ClassExtendsMap", td.getType());
-        Assertions.assertEquals(MapTypeBuilder.class.getName(), td.getTypeBuilderName());
         Assertions.assertEquals(0, td.getProperties().size());
 
         ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
index 3762f3a..24868e9 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
@@ -21,7 +21,6 @@ import org.apache.dubbo.metadata.definition.model.MethodDefinition;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import org.apache.dubbo.metadata.definition.service.ComplexObject;
 import org.apache.dubbo.metadata.definition.service.DemoService;
-
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -58,41 +57,44 @@ public class ServiceDefinitionBuilderTest {
                 String[].class.getCanonicalName(), "java.util.List<java.lang.Integer>", ComplexObject.TestEnum.class.getCanonicalName()}));
         Assertions.assertEquals(findComplexObject.getReturnType(), ComplexObject.class.getCanonicalName());
 
-
         List<TypeDefinition> typeDefinitions = fullServiceDefinition.getTypes();
 
         TypeDefinition topTypeDefinition = null;
         TypeDefinition innerTypeDefinition = null;
         TypeDefinition inner2TypeDefinition = null;
         TypeDefinition inner3TypeDefinition = null;
+        TypeDefinition listTypeDefinition = null;
         for (TypeDefinition typeDefinition : typeDefinitions) {
-            if (typeDefinition.getType().equals(ComplexObject.class.getName())) {
+            if (typeDefinition.getType().equals(ComplexObject.class.getCanonicalName())) {
                 topTypeDefinition = typeDefinition;
-            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getName())) {
+            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject.class.getCanonicalName())) {
                 innerTypeDefinition = typeDefinition;
-            } else if (typeDefinition.getType().contains(ComplexObject.InnerObject2.class.getName())) {
+            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject2.class.getCanonicalName())) {
                 inner2TypeDefinition = typeDefinition;
-            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getName())) {
+            } else if (typeDefinition.getType().equals(ComplexObject.InnerObject3.class.getCanonicalName())) {
                 inner3TypeDefinition = typeDefinition;
+            } else if (typeDefinition.getType().equals("java.util.List<java.lang.Integer>")) {
+                listTypeDefinition = typeDefinition;
             }
         }
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("v").getType(), "long");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("maps").getType(), "java.util.Map<java.lang.String,java.lang.String>");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject").getType(), ComplexObject.InnerObject.class.getName());
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("intList").getType(), "java.util.List<java.lang.Integer>");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("strArrays").getType(), "java.lang.String[]");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject3").getType(), "org.apache.dubbo.metadata.definition.service.ComplexObject.InnerObject3[]");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("testEnum").getType(), "org.apache.dubbo.metadata.definition.service.ComplexObject.TestEnum");
-        Assertions.assertEquals(topTypeDefinition.getProperties().get("innerObject2").getType(), "java.util.Set<org.apache.dubbo.metadata.definition.service.ComplexObject$InnerObject2>");
+        Assertions.assertEquals("long", topTypeDefinition.getProperties().get("v"));
+        Assertions.assertEquals("java.util.Map<java.lang.String,java.lang.String>", topTypeDefinition.getProperties().get("maps"));
+        Assertions.assertEquals(ComplexObject.InnerObject.class.getCanonicalName(), topTypeDefinition.getProperties().get("innerObject"));
+        Assertions.assertEquals("java.util.List<java.lang.Integer>", topTypeDefinition.getProperties().get("intList"));
+        Assertions.assertEquals("java.lang.String[]", topTypeDefinition.getProperties().get("strArrays"));
+        Assertions.assertEquals("org.apache.dubbo.metadata.definition.service.ComplexObject.InnerObject3[]", topTypeDefinition.getProperties().get("innerObject3"));
+        Assertions.assertEquals("org.apache.dubbo.metadata.definition.service.ComplexObject.TestEnum", topTypeDefinition.getProperties().get("testEnum"));
+        Assertions.assertEquals("java.util.Set<org.apache.dubbo.metadata.definition.service.ComplexObject.InnerObject2>", topTypeDefinition.getProperties().get("innerObject2"));
 
-        Assertions.assertSame(innerTypeDefinition.getProperties().get("innerA").getType(), "java.lang.String");
-        Assertions.assertSame(innerTypeDefinition.getProperties().get("innerB").getType(), "int");
+        Assertions.assertSame("java.lang.String", innerTypeDefinition.getProperties().get("innerA"));
+        Assertions.assertSame("int", innerTypeDefinition.getProperties().get("innerB"));
 
-        Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerA2").getType(), "java.lang.String");
-        Assertions.assertSame(inner2TypeDefinition.getProperties().get("innerB2").getType(), "int");
+        Assertions.assertSame("java.lang.String", inner2TypeDefinition.getProperties().get("innerA2"));
+        Assertions.assertSame("int", inner2TypeDefinition.getProperties().get("innerB2"));
 
-        Assertions.assertSame(inner3TypeDefinition.getProperties().get("innerA3").getType(), "java.lang.String");
+        Assertions.assertSame("java.lang.String", inner3TypeDefinition.getProperties().get("innerA3"));
 
+        Assertions.assertEquals(Integer.class.getCanonicalName(), listTypeDefinition.getItems().get(0));
     }
 
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java
index 075a69e..b74e8cd 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java
@@ -27,6 +27,7 @@ import java.util.Map;
  */
 public class Test3TypeBuilder implements TypeBuilder {
     // it is smaller than the implements of TypeBuilder
+    @Override
     public int getPriority(){
         return 10;
     }
@@ -37,7 +38,7 @@ public class Test3TypeBuilder implements TypeBuilder {
     }
 
     @Override
-    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
         return null;
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java
index bf7e9c6..9a1feab 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java
@@ -27,6 +27,7 @@ import java.util.Map;
  */
 public class TestTypeBuilder implements TypeBuilder {
     // it is smaller than the implements of TypeBuilder
+    @Override
     public int getPriority(){
         return -3;
     }
@@ -37,7 +38,7 @@ public class TestTypeBuilder implements TypeBuilder {
     }
 
     @Override
-    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
         return null;
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java b/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java
index a74d7d7..7161dd2 100644
--- a/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java
@@ -16,17 +16,17 @@
  */
 package org.apache.dubbo.metadata.definition.protobuf;
 
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-
 import com.google.protobuf.ByteString;
 import com.google.protobuf.Descriptors;
 import com.google.protobuf.GeneratedMessageV3;
 import com.google.protobuf.ProtocolStringList;
 import com.google.protobuf.UnknownFieldSet;
+import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
@@ -36,7 +36,7 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-public class ProtobufTypeBuilder implements TypeBuilder {
+public class ProtobufTypeBuilder implements TypeBuilder, Prioritized {
     private final Logger logger = LoggerFactory.getLogger(getClass());
     private static final Pattern MAP_PATTERN = Pattern.compile("^java\\.util\\.Map<(\\S+), (\\S+)>$");
     private static final Pattern LIST_PATTERN = Pattern.compile("^java\\.util\\.List<(\\S+)>$");
@@ -56,6 +56,11 @@ public class ProtobufTypeBuilder implements TypeBuilder {
     }
 
     @Override
+    public int getPriority() {
+        return -1;
+    }
+
+    @Override
     public boolean accept(Type type, Class<?> clazz) {
         if (clazz == null) {
             return false;
@@ -65,11 +70,16 @@ public class ProtobufTypeBuilder implements TypeBuilder {
     }
 
     @Override
-    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, TypeDefinition> typeCache) {
-        TypeDefinition typeDefinition = new TypeDefinition(clazz.getName());
+    public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
+        String canonicalName = clazz.getCanonicalName();
+        TypeDefinition typeDefinition = typeCache.get(canonicalName);
+        if (typeDefinition != null) {
+            return typeDefinition;
+        }
         try {
             GeneratedMessageV3.Builder builder = getMessageBuilder(clazz);
             typeDefinition = buildProtobufTypeDefinition(clazz, builder, typeCache);
+            typeCache.put(canonicalName, typeDefinition);
         } catch (Exception e) {
             logger.info("TypeDefinition build failed.", e);
         }
@@ -82,48 +92,50 @@ public class ProtobufTypeBuilder implements TypeBuilder {
         return (GeneratedMessageV3.Builder) method.invoke(null, null);
     }
 
-    private TypeDefinition buildProtobufTypeDefinition(Class<?> clazz, GeneratedMessageV3.Builder builder, Map<Class<?>, TypeDefinition> typeCache) {
-        TypeDefinition typeDefinition = new TypeDefinition(clazz.getName());
+    private TypeDefinition buildProtobufTypeDefinition(Class<?> clazz, GeneratedMessageV3.Builder builder, Map<String, TypeDefinition> typeCache) {
+        String canonicalName = clazz.getCanonicalName();
+        TypeDefinition td = new TypeDefinition(canonicalName);
         if (builder == null) {
-            return typeDefinition;
+            return td;
         }
 
-        Map<String, TypeDefinition> properties = new HashMap<>();
+        Map<String, String> properties = new HashMap<>();
         Method[] methods = builder.getClass().getDeclaredMethods();
         for (Method method : methods) {
             String methodName = method.getName();
 
             if (isSimplePropertySettingMethod(method)) {
                 // property of custom type or primitive type
-                properties.put(generateSimpleFiledName(methodName), TypeDefinitionBuilder.build(method.getGenericParameterTypes()[0], method.getParameterTypes()[0], typeCache));
+                TypeDefinition fieldTd = TypeDefinitionBuilder.build(method.getGenericParameterTypes()[0], method.getParameterTypes()[0], typeCache);
+                properties.put(generateSimpleFiledName(methodName), fieldTd.getType());
             } else if (isMapPropertySettingMethod(method)) {
                 // property of map
                 Type type = method.getGenericParameterTypes()[0];
                 String fieldName = generateMapFieldName(methodName);
                 validateMapType(fieldName, type.toString());
-                properties.put(fieldName, TypeDefinitionBuilder.build(type, method.getParameterTypes()[0], typeCache));
+                TypeDefinition fieldTd = TypeDefinitionBuilder.build(type, method.getParameterTypes()[0], typeCache);
+                properties.put(fieldName, fieldTd.getType());
             } else if (isListPropertyGettingMethod(method)) {
                 // property of list
                 Type type = method.getGenericReturnType();
                 String fieldName = generateListFieldName(methodName);
-                TypeDefinition td;
+                TypeDefinition fieldTd;
                 if (ProtocolStringList.class.isAssignableFrom(method.getReturnType())) {
                     // property defined as "repeated string" transform to ProtocolStringList,
                     // should be build as List<String>.
-                    td = TypeDefinitionBuilder.build(STRING_LIST_TYPE, List.class, typeCache);
+                    fieldTd = TypeDefinitionBuilder.build(STRING_LIST_TYPE, List.class, typeCache);
                 } else {
                     // property without generic type should not be build ex method return List
                     if (!LIST_PATTERN.matcher(type.toString()).matches()) {
                         continue;
                     }
-                    td = TypeDefinitionBuilder.build(type, method.getReturnType(), typeCache);
+                    fieldTd = TypeDefinitionBuilder.build(type, method.getReturnType(), typeCache);
                 }
-                properties.put(fieldName, td);
+                properties.put(fieldName, fieldTd.getType());
             }
         }
-        typeDefinition.setProperties(properties);
-        typeCache.put(clazz, typeDefinition);
-        return typeDefinition;
+        td.setProperties(properties);
+        return td;
     }
 
     /**
diff --git a/dubbo-metadata/dubbo-metadata-definition-protobuf/src/test/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilderTest.java b/dubbo-metadata/dubbo-metadata-definition-protobuf/src/test/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilderTest.java
index e9c8a17..8d789f7 100644
--- a/dubbo-metadata/dubbo-metadata-definition-protobuf/src/test/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilderTest.java
+++ b/dubbo-metadata/dubbo-metadata-definition-protobuf/src/test/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilderTest.java
@@ -21,9 +21,9 @@ import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
 import org.apache.dubbo.metadata.definition.model.MethodDefinition;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import org.apache.dubbo.metadata.definition.protobuf.model.ServiceInterface;
-
 import org.junit.jupiter.api.Test;
 
+import java.util.List;
 import java.util.Map;
 
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -39,6 +39,7 @@ public class ProtobufTypeBuilderTest {
         // TEST Pb Service metaData builder
         FullServiceDefinition serviceDefinition = ServiceDefinitionBuilder.buildFullDefinition(ServiceInterface.class);
         MethodDefinition methodDefinition = serviceDefinition.getMethods().get(0);
+        List<TypeDefinition> types = serviceDefinition.getTypes();
         String parameterName = methodDefinition.getParameterTypes()[0];
         TypeDefinition typeDefinition = null;
         for (TypeDefinition type : serviceDefinition.getTypes()) {
@@ -47,27 +48,41 @@ public class ProtobufTypeBuilderTest {
                 break;
             }
         }
-        Map<String, TypeDefinition> propertiesMap = typeDefinition.getProperties();
+        Map<String, String> propertiesMap = typeDefinition.getProperties();
         assertThat(propertiesMap.size(), is(11));
         assertThat(propertiesMap.containsKey("money"), is(true));
-        assertThat(propertiesMap.get("money").getType(), equalTo("double"));
+        assertThat(getTypeName(propertiesMap.get("money"), types), equalTo("double"));
         assertThat(propertiesMap.containsKey("cash"), is(true));
-        assertThat(propertiesMap.get("cash").getType(), equalTo("float"));
+        assertThat(getTypeName(propertiesMap.get("cash"), types), equalTo("float"));
         assertThat(propertiesMap.containsKey("age"), is(true));
-        assertThat(propertiesMap.get("age").getType(), equalTo("int"));
+        assertThat(getTypeName(propertiesMap.get("age"), types), equalTo("int"));
         assertThat(propertiesMap.containsKey("num"), is(true));
-        assertThat(propertiesMap.get("num").getType(), equalTo("long"));
+        assertThat(getTypeName(propertiesMap.get("num"), types), equalTo("long"));
         assertThat(propertiesMap.containsKey("sex"), is(true));
-        assertThat(propertiesMap.get("sex").getType(), equalTo("boolean"));
+        assertThat(getTypeName(propertiesMap.get("sex"), types), equalTo("boolean"));
         assertThat(propertiesMap.containsKey("name"), is(true));
-        assertThat(propertiesMap.get("name").getType(), equalTo("java.lang.String"));
+        assertThat(getTypeName(propertiesMap.get("name"), types), equalTo("java.lang.String"));
         assertThat(propertiesMap.containsKey("msg"), is(true));
-        assertThat(propertiesMap.get("msg").getType(), equalTo("com.google.protobuf.ByteString"));
+        assertThat(getTypeName(propertiesMap.get("msg"), types),
+                equalTo("com.google.protobuf.ByteString"));
         assertThat(propertiesMap.containsKey("phone"), is(true));
-        assertThat(propertiesMap.get("phone").getType(), equalTo("java.util.List<org.apache.dubbo.metadata.definition.protobuf.model.GooglePB$PhoneNumber>"));
+        assertThat(getTypeName(propertiesMap.get("phone"), types),
+                equalTo("java.util.List<org.apache.dubbo.metadata.definition.protobuf.model.GooglePB.PhoneNumber>"));
         assertThat(propertiesMap.containsKey("doubleMap"), is(true));
-        assertThat(propertiesMap.get("doubleMap").getType(), equalTo("java.util.Map<java.lang.String,org.apache.dubbo.metadata.definition.protobuf.model.GooglePB$PhoneNumber>"));
-        assertThat(propertiesMap.get("bytesList").getType(), equalTo("java.util.List<com.google.protobuf.ByteString>"));
-        assertThat(propertiesMap.get("bytesMap").getType(), equalTo("java.util.Map<java.lang.String,com.google.protobuf.ByteString>"));
+        assertThat(getTypeName(propertiesMap.get("doubleMap"), types),
+                equalTo("java.util.Map<java.lang.String,org.apache.dubbo.metadata.definition.protobuf.model.GooglePB.PhoneNumber>"));
+        assertThat(getTypeName(propertiesMap.get("bytesList"), types),
+                equalTo("java.util.List<com.google.protobuf.ByteString>"));
+        assertThat(getTypeName(propertiesMap.get("bytesMap"), types),
+                equalTo("java.util.Map<java.lang.String,com.google.protobuf.ByteString>"));
+    }
+
+    private static String getTypeName(String type, List<TypeDefinition> types) {
+        for (TypeDefinition typeDefinition : types) {
+            if (type.equals(typeDefinition.getType())) {
+                return typeDefinition.getType();
+            }
+        }
+        return type;
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilder.java
index a53f334..26aa10d 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilder.java
@@ -22,15 +22,16 @@ import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.type.ArrayType;
 import javax.lang.model.type.TypeMirror;
 import java.lang.reflect.Array;
+import java.util.Map;
 
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isArrayType;
 
 /**
- * {@link TypeDefinitionBuilder} for Java {@link Array}
+ * {@link TypeBuilder} for Java {@link Array}
  *
  * @since 2.7.6
  */
-public class ArrayTypeDefinitionBuilder implements TypeDefinitionBuilder<ArrayType> {
+public class ArrayTypeDefinitionBuilder implements TypeBuilder<ArrayType> {
 
     @Override
     public boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
@@ -38,9 +39,13 @@ public class ArrayTypeDefinitionBuilder implements TypeDefinitionBuilder<ArrayTy
     }
 
     @Override
-    public void build(ProcessingEnvironment processingEnv, ArrayType type, TypeDefinition typeDefinition) {
+    public TypeDefinition build(ProcessingEnvironment processingEnv, ArrayType type, Map<String, TypeDefinition> typeCache) {
+        TypeDefinition typeDefinition = new TypeDefinition(type.toString());
         TypeMirror componentType = type.getComponentType();
-        typeDefinition.getItems().add(TypeDefinitionBuilder.build(processingEnv, componentType));
+        TypeDefinition subTypeDefinition = TypeDefinitionBuilder.build(processingEnv, componentType, typeCache);
+        typeDefinition.getItems()
+                .add(subTypeDefinition.getType());
+        return typeDefinition;
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilder.java
index 0141ff1..7f7be24 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilder.java
@@ -25,10 +25,11 @@ import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.Elements;
 import javax.lang.model.util.Types;
 import java.util.Collection;
+import java.util.Map;
 import java.util.Objects;
 
 /**
- * {@link TypeDefinitionBuilder} for Java {@link Collection}
+ * {@link TypeBuilder} for Java {@link Collection}
  *
  * @since 2.7.6
  */
@@ -45,13 +46,17 @@ public class CollectionTypeDefinitionBuilder implements DeclaredTypeDefinitionBu
     }
 
     @Override
-    public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+    public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
+        String typeName = type.toString();
+        TypeDefinition typeDefinition = new TypeDefinition(typeName);
         // Generic Type arguments
         type.getTypeArguments()
                 .stream()
-                .map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument)) // build the TypeDefinition from typeArgument
+                .map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument, typeCache)) // build the TypeDefinition from typeArgument
                 .filter(Objects::nonNull)
+                .map(TypeDefinition::getType)
                 .forEach(typeDefinition.getItems()::add);                              // Add into the declared TypeDefinition
+        return typeDefinition;
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/DeclaredTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/DeclaredTypeDefinitionBuilder.java
index a4d0106..744e064 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/DeclaredTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/DeclaredTypeDefinitionBuilder.java
@@ -23,11 +23,11 @@ import javax.lang.model.type.TypeMirror;
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofDeclaredType;
 
 /**
- * An interface of {@link TypeDefinitionBuilder} for {@link DeclaredType}
+ * An interface of {@link TypeBuilder} for {@link DeclaredType}
  *
  * @since 2.7.6
  */
-public interface DeclaredTypeDefinitionBuilder extends TypeDefinitionBuilder<DeclaredType> {
+public interface DeclaredTypeDefinitionBuilder extends TypeBuilder<DeclaredType> {
 
     @Override
     default boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilder.java
index 20c3889..b766e38 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilder.java
@@ -24,11 +24,13 @@ import javax.lang.model.element.Element;
 import javax.lang.model.element.Name;
 import javax.lang.model.type.DeclaredType;
 
+import java.util.Map;
+
 import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.getDeclaredFields;
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isEnumType;
 
 /**
- * {@link TypeDefinitionBuilder} for Java {@link Enum}
+ * {@link TypeBuilder} for Java {@link Enum}
  *
  * @since 2.7.6
  */
@@ -40,12 +42,14 @@ public class EnumTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder
     }
 
     @Override
-    public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+    public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
+        TypeDefinition typeDefinition = new TypeDefinition(type.toString());
         getDeclaredFields(type, FieldUtils::isEnumMemberField)
                 .stream()
                 .map(Element::getSimpleName)
                 .map(Name::toString)
                 .forEach(typeDefinition.getEnums()::add);
+        return typeDefinition;
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilder.java
index c160111..83c3f8f 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilder.java
@@ -22,12 +22,14 @@ import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.DeclaredType;
 
+import java.util.Map;
+
 import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.getNonStaticFields;
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getType;
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isClassType;
 
 /**
- * {@link TypeDefinitionBuilder} for General Object
+ * {@link TypeBuilder} for General Object
  *
  * @since 2.7.6
  */
@@ -39,23 +41,26 @@ public class GeneralTypeDefinitionBuilder implements DeclaredTypeDefinitionBuild
     }
 
     @Override
-    public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+    public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
 
         String typeName = type.toString();
 
         TypeElement typeElement = getType(processingEnv, typeName);
 
-        buildProperties(processingEnv, typeElement, typeDefinition);
+        return buildProperties(processingEnv, typeElement, typeCache);
     }
 
-    protected void buildProperties(ProcessingEnvironment processingEnv, TypeElement type, TypeDefinition definition) {
+    protected TypeDefinition buildProperties(ProcessingEnvironment processingEnv, TypeElement type, Map<String, TypeDefinition> typeCache) {
+        TypeDefinition definition = new TypeDefinition(type.toString());
         getNonStaticFields(type).forEach(field -> {
             String fieldName = field.getSimpleName().toString();
-            TypeDefinition propertyType = TypeDefinitionBuilder.build(processingEnv, field);
+            TypeDefinition propertyType = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
             if (propertyType != null) {
-                definition.getProperties().put(fieldName, propertyType);
+                typeCache.put(propertyType.getType(), propertyType);
+                definition.getProperties().put(fieldName, propertyType.getType());
             }
         });
+        return definition;
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilder.java
index d05e4bb..1045fcb 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilder.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import java.util.Objects;
 
 /**
- * {@link TypeDefinitionBuilder} for Java {@link Map}
+ * {@link TypeBuilder} for Java {@link Map}
  *
  * @since 2.7.6
  */
@@ -45,14 +45,16 @@ public class MapTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder {
     }
 
     @Override
-    public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+    public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
+        TypeDefinition typeDefinition = new TypeDefinition(type.toString());
         // Generic Type arguments
         type.getTypeArguments()
                 .stream()
-                .map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument)) // build the TypeDefinition from typeArgument
+                .map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument, typeCache)) // build the TypeDefinition from typeArgument
                 .filter(Objects::nonNull)
+                .map(TypeDefinition::getType)
                 .forEach(typeDefinition.getItems()::add);                              // Add into the declared TypeDefinition
-
+        return typeDefinition;
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MethodDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MethodDefinitionBuilder.java
index b579095..c91f96f 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MethodDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MethodDefinitionBuilder.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.ExecutableElement;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getMethodName;
@@ -36,18 +37,18 @@ import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.g
  */
 public interface MethodDefinitionBuilder {
 
-    static MethodDefinition build(ProcessingEnvironment processingEnv, ExecutableElement method) {
+    static MethodDefinition build(ProcessingEnvironment processingEnv, ExecutableElement method, Map<String, TypeDefinition> typeCache) {
         MethodDefinition methodDefinition = new MethodDefinition();
         methodDefinition.setName(getMethodName(method));
         methodDefinition.setReturnType(getReturnType(method));
         methodDefinition.setParameterTypes(getMethodParameterTypes(method));
-        methodDefinition.setParameters(getMethodParameters(processingEnv, method));
+        methodDefinition.setParameters(getMethodParameters(processingEnv, method, typeCache));
         return methodDefinition;
     }
 
-    static List<TypeDefinition> getMethodParameters(ProcessingEnvironment processingEnv, ExecutableElement method) {
+    static List<TypeDefinition> getMethodParameters(ProcessingEnvironment processingEnv, ExecutableElement method, Map<String, TypeDefinition> typeCache) {
         return method.getParameters().stream()
-                .map(element -> TypeDefinitionBuilder.build(processingEnv, element))
+                .map(element -> TypeDefinitionBuilder.build(processingEnv, element, typeCache))
                 .collect(Collectors.toList());
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilder.java
index 3c7b603..9c7ede8 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilder.java
@@ -22,14 +22,16 @@ import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.type.PrimitiveType;
 import javax.lang.model.type.TypeMirror;
 
+import java.util.Map;
+
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isPrimitiveType;
 
 /**
- * {@link TypeDefinitionBuilder} for Java {@link PrimitiveType primitve type}
+ * {@link TypeBuilder} for Java {@link PrimitiveType primitve type}
  *
  * @since 2.7.6
  */
-public class PrimitiveTypeDefinitionBuilder implements TypeDefinitionBuilder<PrimitiveType> {
+public class PrimitiveTypeDefinitionBuilder implements TypeBuilder<PrimitiveType> {
 
     @Override
     public boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
@@ -37,8 +39,9 @@ public class PrimitiveTypeDefinitionBuilder implements TypeDefinitionBuilder<Pri
     }
 
     @Override
-    public void build(ProcessingEnvironment processingEnv, PrimitiveType type, TypeDefinition typeDefinition) {
-        // DO NOTHING
+    public TypeDefinition build(ProcessingEnvironment processingEnv, PrimitiveType type, Map<String, TypeDefinition> typeCache) {
+        TypeDefinition typeDefinition = new TypeDefinition(type.toString());
+        return typeDefinition;
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilder.java
index a5616e6..39c7bf6 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilder.java
@@ -17,10 +17,15 @@
 package org.apache.dubbo.metadata.annotation.processing.builder;
 
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.TypeElement;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
 import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getPublicNonStaticMethods;
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getHierarchicalTypes;
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getResourceName;
@@ -38,19 +43,21 @@ public interface ServiceDefinitionBuilder {
         serviceDefinition.setCanonicalName(type.toString());
         serviceDefinition.setCodeSource(getResourceName(type.toString()));
 
+        Map<String, TypeDefinition> types = new HashMap<>();
+
         // Get all super types and interface excluding the specified type
         // and then the result will be added into ServiceDefinition#getTypes()
         getHierarchicalTypes(type.asType(), Object.class)
-                .stream()
-                .map(t -> TypeDefinitionBuilder.build(processingEnv, t))
-                .forEach(serviceDefinition.getTypes()::add);
+                .forEach(t -> TypeDefinitionBuilder.build(processingEnv, t, types));
 
         // Get all declared methods that will be added into ServiceDefinition#getMethods()
         getPublicNonStaticMethods(type, Object.class)
                 .stream()
-                .map(method -> MethodDefinitionBuilder.build(processingEnv, method))
+                .map(method -> MethodDefinitionBuilder.build(processingEnv, method, types))
                 .forEach(serviceDefinition.getMethods()::add);
 
+        serviceDefinition.setTypes(new ArrayList<>(types.values()));
+
         return serviceDefinition;
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilder.java
index 620988f..627345a 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilder.java
@@ -22,11 +22,13 @@ import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.type.DeclaredType;
 
+import java.util.Map;
+
 import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isSimpleType;
 
 
 /**
- * {@link TypeDefinitionBuilder} for {@link TypeUtils#SIMPLE_TYPES Java Simple Type}
+ * {@link TypeBuilder} for {@link TypeUtils#SIMPLE_TYPES Java Simple Type}
  *
  * @since 2.7.6
  */
@@ -38,8 +40,9 @@ public class SimpleTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilde
     }
 
     @Override
-    public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
-        //  DO NOTHING
+    public TypeDefinition build(ProcessingEnvironment processingEnv, DeclaredType type, Map<String, TypeDefinition> typeCache) {
+        TypeDefinition td = new TypeDefinition(type.toString());
+        return td;
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeBuilder.java
new file mode 100644
index 0000000..9c28936
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeBuilder.java
@@ -0,0 +1,31 @@
+package org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.TypeMirror;
+import java.util.Map;
+
+@SPI
+public interface TypeBuilder<T extends TypeMirror> extends Prioritized {
+
+    /**
+     * Test the specified {@link TypeMirror type} is accepted or not
+     *
+     * @param processingEnv {@link ProcessingEnvironment}
+     * @param type          {@link TypeMirror type}
+     * @return <code>true</code> if accepted
+     */
+    boolean accept(ProcessingEnvironment processingEnv, TypeMirror type);
+
+    /**
+     * Build the instance of {@link TypeDefinition}
+     *
+     * @param processingEnv  {@link ProcessingEnvironment}
+     * @param type           {@link T type}
+     * @return an instance of {@link TypeDefinition}
+     */
+    TypeDefinition build(ProcessingEnvironment processingEnv, T type, Map<String, TypeDefinition> typeCache);
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeDefinitionBuilder.java
index e65bc1d..edceedf 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeDefinitionBuilder.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeDefinitionBuilder.java
@@ -16,13 +16,14 @@
  */
 package org.apache.dubbo.metadata.annotation.processing.builder;
 
-import org.apache.dubbo.common.extension.SPI;
 import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.metadata.annotation.processing.builder.TypeBuilder;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.Element;
 import javax.lang.model.type.TypeMirror;
+import java.util.Map;
 
 import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
 
@@ -31,37 +32,17 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad
  *
  * @since 2.7.6
  */
-@SPI
 public interface TypeDefinitionBuilder<T extends TypeMirror> extends Prioritized {
 
     /**
-     * Test the specified {@link TypeMirror type} is accepted or not
-     *
-     * @param processingEnv {@link ProcessingEnvironment}
-     * @param type          {@link TypeMirror type}
-     * @return <code>true</code> if accepted
-     */
-    boolean accept(ProcessingEnvironment processingEnv, TypeMirror type);
-
-    /**
-     * Build the instance of {@link TypeDefinition}
-     *
-     * @param processingEnv  {@link ProcessingEnvironment}
-     * @param type           {@link T type}
-     * @param typeDefinition {@link TypeDefinition} to be built
-     * @return an instance of {@link TypeDefinition}
-     */
-    void build(ProcessingEnvironment processingEnv, T type, TypeDefinition typeDefinition);
-
-    /**
      * Build the instance of {@link TypeDefinition} from the specified {@link Element element}
      *
      * @param processingEnv {@link ProcessingEnvironment}
      * @param element       {@link Element source element}
      * @return non-null
      */
-    static TypeDefinition build(ProcessingEnvironment processingEnv, Element element) {
-        TypeDefinition typeDefinition = build(processingEnv, element.asType());
+    static TypeDefinition build(ProcessingEnvironment processingEnv, Element element, Map<String, TypeDefinition> typeCache) {
+        TypeDefinition typeDefinition = build(processingEnv, element.asType(), typeCache);
         // Comment this code for the compatibility
         // typeDefinition.set$ref(element.toString());
         return typeDefinition;
@@ -74,23 +55,23 @@ public interface TypeDefinitionBuilder<T extends TypeMirror> extends Prioritized
      * @param type          {@link TypeMirror type}
      * @return non-null
      */
-    static TypeDefinition build(ProcessingEnvironment processingEnv, TypeMirror type) {
-        String typeName = type.toString();
-        TypeDefinition typeDefinition = new TypeDefinition(typeName);
-
+    static TypeDefinition build(ProcessingEnvironment processingEnv, TypeMirror type, Map<String, TypeDefinition> typeCache) {
         // Build by all instances of TypeDefinitionBuilder that were loaded By Java SPI
 
-        getExtensionLoader(TypeDefinitionBuilder.class)
+        TypeDefinition typeDefinition = getExtensionLoader(TypeBuilder.class)
                 .getSupportedExtensionInstances()
                 .stream()
 //        load(TypeDefinitionBuilder.class, TypeDefinitionBuilder.class.getClassLoader())
                 .filter(builder -> builder.accept(processingEnv, type))
                 .findFirst()
-                .ifPresent(builder -> {
-                    builder.build(processingEnv, type, typeDefinition);
+                .map(builder -> {
+                    return builder.build(processingEnv, type, typeCache);
                     // typeDefinition.setTypeBuilderName(builder.getClass().getName());
-                });
+                }).orElse(null);
 
+        if (typeDefinition != null) {
+            typeCache.put(typeDefinition.getType(), typeDefinition);
+        }
         return typeDefinition;
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractServiceRestMetadataResolver.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractServiceRestMetadataResolver.java
index d2e400a..9609d93 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractServiceRestMetadataResolver.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractServiceRestMetadataResolver.java
@@ -215,7 +215,7 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest
 
     protected MethodDefinition resolveMethodDefinition(ProcessingEnvironment processingEnv, TypeElement serviceType,
                                                        ExecutableElement method) {
-        return build(processingEnv, method);
+        return build(processingEnv, method, new HashMap<>());
     }
 
     protected void processAnnotatedMethodParameters(ExecutableElement method, TypeElement type,
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/DefaultValueParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/DefaultValueParameterProcessor.java
index 8568235..f5c5a62 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/DefaultValueParameterProcessor.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/DefaultValueParameterProcessor.java
@@ -69,6 +69,7 @@ public class DefaultValueParameterProcessor extends AbstractAnnotatedMethodParam
         }
     }
 
+    @Override
     public int getPriority() {
         return MIN_PRIORITY;
     }
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeBuilder
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder
rename to dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeBuilder
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilderTest.java
index 3290a8a..d3e7ff1 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilderTest.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilderTest.java
@@ -26,6 +26,8 @@ import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 import java.util.function.BiConsumer;
 import java.util.stream.Stream;
@@ -108,10 +110,12 @@ public class ArrayTypeDefinitionBuilderTest extends AbstractAnnotationProcessing
     }
 
     static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field,
-                                             String expectedType, String compositeType, TypeDefinitionBuilder builder,
+                                             String expectedType, String compositeType, TypeBuilder builder,
                                              BiConsumer<TypeDefinition, TypeDefinition>... assertions) {
-        TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
-        TypeDefinition subTypeDefinition = typeDefinition.getItems().get(0);
+        Map<String, TypeDefinition> typeCache = new HashMap<>();
+        TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
+        String subTypeName = typeDefinition.getItems().get(0);
+        TypeDefinition subTypeDefinition = typeCache.get(subTypeName);
         assertEquals(expectedType, typeDefinition.getType());
 //        assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
         assertEquals(compositeType, subTypeDefinition.getType());
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilderTest.java
index 1157584..aaea5df 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilderTest.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilderTest.java
@@ -23,10 +23,11 @@ import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import org.junit.jupiter.api.Test;
 
 import javax.lang.model.element.TypeElement;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 
 import static java.util.Arrays.asList;
-import static org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder.build;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -58,7 +59,8 @@ public class EnumTypeDefinitionBuilderTest extends AbstractAnnotationProcessingT
     @Test
     public void testBuild() {
         TypeElement typeElement = getType(Color.class);
-        TypeDefinition typeDefinition = build(processingEnv, typeElement);
+        Map<String, TypeDefinition> typeCache = new HashMap<>();
+        TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, typeElement, typeCache);
         assertEquals(Color.class.getName(), typeDefinition.getType());
         assertEquals(asList("RED", "YELLOW", "BLUE"), typeDefinition.getEnums());
 //        assertEquals(typeDefinition.getTypeBuilderName(), builder.getClass().getName());
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilderTest.java
index f7b32b5..a415277 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilderTest.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilderTest.java
@@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 import java.util.function.BiConsumer;
 import java.util.stream.Stream;
@@ -61,11 +63,11 @@ public class MapTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTe
     protected void beforeEach() {
         builder = new MapTypeDefinitionBuilder();
         TypeElement testType = getType(MapTypeModel.class);
-        stringsField = findField( testType, "strings");
-        colorsField = findField( testType, "colors");
-        primitiveTypeModelsField = findField( testType, "primitiveTypeModels");
-        modelsField = findField( testType, "models");
-        modelArraysField = findField( testType, "modelArrays");
+        stringsField = findField(testType, "strings");
+        colorsField = findField(testType, "colors");
+        primitiveTypeModelsField = findField(testType, "primitiveTypeModels");
+        modelsField = findField(testType, "models");
+        modelArraysField = findField(testType, "modelArrays");
 
         assertEquals("strings", stringsField.getSimpleName().toString());
         assertEquals("colors", colorsField.getSimpleName().toString());
@@ -119,11 +121,14 @@ public class MapTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTe
 
     static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field,
                                              String expectedType, String keyType, String valueType,
-                                             TypeDefinitionBuilder builder,
+                                             TypeBuilder builder,
                                              BiConsumer<TypeDefinition, TypeDefinition>... assertions) {
-        TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
-        TypeDefinition keyTypeDefinition = typeDefinition.getItems().get(0);
-        TypeDefinition valueTypeDefinition = typeDefinition.getItems().get(1);
+        Map<String, TypeDefinition> typeCache = new HashMap<>();
+        TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
+        String keyTypeName = typeDefinition.getItems().get(0);
+        TypeDefinition keyTypeDefinition = typeCache.get(keyTypeName);
+        String valueTypeName = typeDefinition.getItems().get(1);
+        TypeDefinition valueTypeDefinition = typeCache.get(valueTypeName);
         assertEquals(expectedType, typeDefinition.getType());
 //        assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
         assertEquals(keyType, keyTypeDefinition.getType());
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilderTest.java
index adc2512..0e5655b 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilderTest.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilderTest.java
@@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 
 import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.findField;
@@ -113,18 +115,18 @@ public class PrimitiveTypeDefinitionBuilderTest extends AbstractAnnotationProces
         buildAndAssertTypeDefinition(processingEnv, dField, builder);
     }
 
-    static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field, TypeDefinitionBuilder builder) {
-        TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
+    static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field, TypeBuilder builder) {
+        Map<String, TypeDefinition> typeCache = new HashMap<>();
+        TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field, typeCache);
         assertBasicTypeDefinition(typeDefinition, field.asType().toString(), builder);
 //        assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
     }
 
-    static void assertBasicTypeDefinition(TypeDefinition typeDefinition, String type, TypeDefinitionBuilder builder) {
+    static void assertBasicTypeDefinition(TypeDefinition typeDefinition, String type, TypeBuilder builder) {
         assertEquals(type, typeDefinition.getType());
 //        assertEquals(builder.getClass().getName(), typeDefinition.getTypeBuilderName());
         assertTrue(typeDefinition.getProperties().isEmpty());
         assertTrue(typeDefinition.getItems().isEmpty());
         assertTrue(typeDefinition.getEnums().isEmpty());
-        assertNull(typeDefinition.getId());
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilderTest.java
index 7f21cef..a2477cc 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilderTest.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilderTest.java
@@ -18,10 +18,13 @@ package org.apache.dubbo.metadata.annotation.processing.builder;
 
 import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import org.apache.dubbo.metadata.tools.TestServiceImpl;
 
 import org.junit.jupiter.api.Test;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.Set;
 
 import static org.apache.dubbo.metadata.annotation.processing.builder.ServiceDefinitionBuilder.build;
@@ -49,16 +52,32 @@ public class ServiceDefinitionBuilderTest extends AbstractAnnotationProcessingTe
         ServiceDefinition serviceDefinition = build(processingEnv, getType(TestServiceImpl.class));
         assertEquals(TestServiceImpl.class.getTypeName(), serviceDefinition.getCanonicalName());
         assertEquals("org/apache/dubbo/metadata/tools/TestServiceImpl.class", serviceDefinition.getCodeSource());
+
         // types
-        int i = 0;
-        assertEquals("org.apache.dubbo.metadata.tools.TestServiceImpl", serviceDefinition.getTypes().get(i++).getType());
-        assertEquals("org.apache.dubbo.metadata.tools.GenericTestService", serviceDefinition.getTypes().get(i++).getType());
-        assertEquals("org.apache.dubbo.metadata.tools.DefaultTestService", serviceDefinition.getTypes().get(i++).getType());
-        assertEquals("org.apache.dubbo.metadata.tools.TestService", serviceDefinition.getTypes().get(i++).getType());
-        assertEquals("java.lang.AutoCloseable", serviceDefinition.getTypes().get(i++).getType());
-        assertEquals("java.io.Serializable", serviceDefinition.getTypes().get(i++).getType());
-        assertEquals("java.util.EventListener", serviceDefinition.getTypes().get(i++).getType());
+        List<String> typeNames = Arrays.asList(
+                "org.apache.dubbo.metadata.tools.TestServiceImpl",
+                "org.apache.dubbo.metadata.tools.GenericTestService",
+                "org.apache.dubbo.metadata.tools.DefaultTestService",
+                "org.apache.dubbo.metadata.tools.TestService",
+                "java.lang.AutoCloseable",
+                "java.io.Serializable",
+                "java.util.EventListener"
+        );
+        for (String typeName : typeNames) {
+            String gotTypeName = getTypeName(typeName, serviceDefinition.getTypes());
+            assertEquals(typeName, gotTypeName);
+        }
+
         // methods
         assertEquals(14, serviceDefinition.getMethods().size());
     }
+
+    private static String getTypeName(String type, List<TypeDefinition> types) {
+        for (TypeDefinition typeDefinition : types) {
+            if (type.equals(typeDefinition.getType())) {
+                return typeDefinition.getType();
+            }
+        }
+        return type;
+    }
 }