private ObjectWriter getObjectWriterInternal(Type objectType, Class objectClass, boolean fieldBased) {
        Class superclass = objectClass.getSuperclass();
        if (!objectClass.isEnum()
                && superclass != null
                && superclass.isEnum()
        ) {
            return getObjectWriter(superclass, superclass, fieldBased);
        }

        final String className = objectClass.getName();
        if (fieldBased) {
            if (superclass != null
                    && superclass != Object.class
                    && "com.google.protobuf.GeneratedMessageV3".equals(superclass.getName())) {
                fieldBased = false;
            } else {
                switch (className) {
                    case "springfox.documentation.spring.web.json.Json":
                    case "cn.hutool.json.JSONArray":
                    case "cn.hutool.json.JSONObject":
                    case "cn.hutool.core.map.CaseInsensitiveMap":
                    case "cn.hutool.core.map.CaseInsensitiveLinkedMap":
                        fieldBased = false;
                        break;
                    default:
                        break;
                }
            }
        } else {
            switch (className) {
                case "org.springframework.core.ResolvableType":
                    fieldBased = true;
                    break;
                default:
                    break;
            }
        }

        ObjectWriter objectWriter = fieldBased
                ? cacheFieldBased.get(objectType)
                : cache.get(objectType);

        if (objectWriter != null) {
            return objectWriter;
        }

        if (TypeUtils.isProxy(objectClass)) {
            Class<?> proxyTarget = superclass;
            if (proxyTarget == Object.class) {
                Class[] interfaces = objectClass.getInterfaces();
                for (Class<?> i : interfaces) {
                    if (!TypeUtils.isProxy(i)) {
                        proxyTarget = i;
                        break;
                    }
                }
            }
            if (objectClass == objectType) {
                objectType = proxyTarget;
            }
            objectClass = proxyTarget;
            if (fieldBased) {
                fieldBased = false;
                objectWriter = cacheFieldBased.get(objectType);
            } else {
                objectWriter = cache.get(objectType);
            }
            if (objectWriter != null) {
                return objectWriter;
            }
        }

        boolean useModules = true;
        if (fieldBased) {
            if (Iterable.class.isAssignableFrom(objectClass)
                    && !Collection.class.isAssignableFrom(objectClass)) {
                useModules = false;
            }
        }

        if (useModules) {
            for (int i = 0; i < modules.size(); i++) {
                ObjectWriterModule module = modules.get(i);
                objectWriter = module.getObjectWriter(objectType, objectClass);
                if (objectWriter != null) {
                    ObjectWriter previous = fieldBased
                            ? cacheFieldBased.putIfAbsent(objectType, objectWriter)
                            : cache.putIfAbsent(objectType, objectWriter);

                    if (previous != null) {
                        objectWriter = previous;
                    }
                    return objectWriter;
                }
            }
        }

        switch (className) {
            case "com.google.common.collect.HashMultimap":
            case "com.google.common.collect.LinkedListMultimap":
            case "com.google.common.collect.LinkedHashMultimap":
            case "com.google.common.collect.ArrayListMultimap":
            case "com.google.common.collect.TreeMultimap":
                objectWriter = GuavaSupport.createAsMapWriter(objectClass);
                break;
            case "com.google.common.collect.AbstractMapBasedMultimap$RandomAccessWrappedList":
                objectWriter = ObjectWriterImplList.INSTANCE;
                break;
            case "com.alibaba.fastjson.JSONObject":
                objectWriter = ObjectWriterImplMap.of(objectClass);
                break;
            case "android.net.Uri$OpaqueUri":
            case "android.net.Uri$HierarchicalUri":
            case "android.net.Uri$StringUri":
                objectWriter = ObjectWriterImplToString.INSTANCE;
                break;
            case "com.clickhouse.data.value.UnsignedLong":
                objectWriter = new ObjectWriterImplToString(true);
            default:
                break;
        }

        if (objectWriter == null
                && (!fieldBased)
                && Map.class.isAssignableFrom(objectClass)
                && BeanUtils.isExtendedMap(objectClass)) {
            return ObjectWriterImplMap.of(objectClass);
        }

        if (objectWriter == null) {
            ObjectWriterCreator creator = getCreator();
            objectWriter = creator.createObjectWriter(
                    objectClass,
                    fieldBased ? JSONWriter.Feature.FieldBased.mask : 0,
                    this
            );
            ObjectWriter previous = fieldBased
                    ? cacheFieldBased.putIfAbsent(objectType, objectWriter)
                    : cache.putIfAbsent(objectType, objectWriter);

            if (previous != null) {
                objectWriter = previous;
            }
        }
        return objectWriter;
    }
@deprecated only use compatible with fastjson 1.x
core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterProvider.java