【Spring源码分析】06-ResolvableType

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

前两篇博客中很多地方都是用到了ResolvableType获取类型信息,这篇就来详细看看它。

ResolvableType封装了Java的Type,提供了getSuperType()方法访问父类型,getInterfaces()反回实现的接口,getGeneric()获取泛型参数,resolve()转化为Class对象。那么什么事Java的Type呢,可以看出Type有四个子接口,一个子类。每种类型代表啥意思可以参考这篇文章《Java Type详解》。下面看看ResolvableType具体实现。

20191017100337\_1.png

ResolvableType的构造函数都是私有的,提供了四类实例化对象的静态方法:

  • forField(Field):获取指定字段的类型
  • forMethodParameter(Method, int):获取指定方法的指定形参的类型
  • forMethodReturnType(Method):获取指定方法的返回值的类型
  • forClass(Class):直接封装指定的类型

每个方法最终都会调用同一个构造方法

    static ResolvableType forType(
            @Nullable Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver);

先来看看forField()方法:

    public static ResolvableType forField(Field field) {
       Assert.notNull(field, "Field must not be null");
       return forType(null, new FieldTypeProvider(field), null);
    }

首先将field封装成FieldTypeProvider,然后调用上述都会使用的forType()方法。FieldTypeProvider实现了TypeProvider接口,该接口有两个方法,对于FieldTypeProvider就是返回字段的类型Class对象和该字段本身的Field对象。

    interface TypeProvider extends Serializable {
       @Nullable
       Type getType();
       @Nullable
       default Object getSource() {
          return null;
       }
    }
    static class FieldTypeProvider implements TypeProvider {
       private final String fieldName;
       private final Class<?> declaringClass;
       private transient Field field;
       public FieldTypeProvider(Field field) {
          this.fieldName = field.getName();
          this.declaringClass = field.getDeclaringClass();
          this.field = field;
       }

       @Override
       public Type getType() {
          return this.field.getGenericType();
       }

       @Override
       public Object getSource() {
          return this.field;
       }

       private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
          inputStream.defaultReadObject();
          try {
             this.field = this.declaringClass.getDeclaredField(this.fieldName);
          }
          catch (Throwable ex) {
             throw new IllegalStateException("Could not find original class structure", ex);
          }
       }
    }

下面看一下都会用到的forType()方法。

    static ResolvableType forType(
          @Nullable Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) {
       if (type == null && typeProvider != null) {
          type = SerializableTypeWrapper.forTypeProvider(typeProvider);
       }
       if (type == null) {
          return NONE;
       }
       // For simple Class references, build the wrapper right away -
       // no expensive resolution necessary, so not worth caching...
       if (type instanceof Class) {
          return new ResolvableType(type, typeProvider, variableResolver, (ResolvableType) null);
       }
       // Purge empty entries on access since we don't have a clean-up thread or the like.
       cache.purgeUnreferencedEntries();
       // Check the cache - we may have a ResolvableType which has been resolved before...
       ResolvableType resultType = new ResolvableType(type, typeProvider, variableResolver);
       ResolvableType cachedType = cache.get(resultType);
       if (cachedType == null) {
          cachedType = new ResolvableType(type, typeProvider, variableResolver, resultType.hash);
          cache.put(cachedType, cachedType);
       }
       resultType.resolved = cachedType.resolved;
       return resultType;
    }

上面代码获取type时没有简单的调用typeProvider.getType(),而是使用SerializableTypeWrapper.forTypeProvider(typeProvider)包装了一个代理类,这么做的目的是为了type可以序列化,因为代理类实现了Serializable接口。

    static Type forTypeProvider(final TypeProvider provider) {
       Assert.notNull(provider, "Provider must not be null");
       Type providedType = provider.getType();
       if (providedType == null) {
          return null;
       }
       if (providedType instanceof Serializable) {
          return providedType;
       }
       Type cached = cache.get(providedType);
       if (cached != null) {
          return cached;
       }
       for (Class<?> type : SUPPORTED_SERIALIZABLE_TYPES) {
          if (type.isAssignableFrom(providedType.getClass())) {
             ClassLoader classLoader = provider.getClass().getClassLoader();
             Class<?>[] interfaces = new Class<?>[] {type, SerializableTypeProxy.class, Serializable.class};
             InvocationHandler handler = new TypeProxyInvocationHandler(provider);
             cached = (Type) Proxy.newProxyInstance(classLoader, interfaces, handler);
             cache.put(providedType, cached);
             return cached;
          }
       }
       throw new IllegalArgumentException("Unsupported Type class: " + providedType.getClass().getName());
    }

TypeProxyInvocationHandler。

    public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
       if (method.getName().equals("equals") && args != null) {
          Object other = args[0];
          // Unwrap proxies for speed
          if (other instanceof Type) {
             other = unwrap((Type) other);
          }
          return ObjectUtils.nullSafeEquals(this.provider.getType(), other);
       }
       else if (method.getName().equals("hashCode")) {
          return ObjectUtils.nullSafeHashCode(this.provider.getType());
       }
       else if (method.getName().equals("getTypeProvider")) {
          return this.provider;
       }

       if (Type.class == method.getReturnType() && args == null) {
          return forTypeProvider(new MethodInvokeTypeProvider(this.provider, method, -1));
       }
       else if (Type[].class == method.getReturnType() && args == null) {
          Type[] result = new Type[((Type[]) method.invoke(this.provider.getType())).length];
          for (int i = 0; i < result.length; i++) {
             result[i] = forTypeProvider(new MethodInvokeTypeProvider(this.provider, method, i));
          }
          return result;
       }

       try {
          return method.invoke(this.provider.getType(), args);
       }
       catch (InvocationTargetException ex) {
          throw ex.getTargetException();
       }
    }

在结合ResolvableType的getType()方法看一下,如果type是代理对象则先调用getTypeProvider()方法得到TypeProvider在调用getType()方法获取到Type。

    public Type getType() {
       return SerializableTypeWrapper.unwrap(this.type);
    }
    public static <T extends Type> T unwrap(T type) {
       Type unwrapped = type;
       while (unwrapped instanceof SerializableTypeProxy) {
          unwrapped = ((SerializableTypeProxy) type).getTypeProvider().getType();
       }
       return (unwrapped != null ? (T) unwrapped : type);
    }

获取type先通过构造函数实例化一个resultType,这个resultType的resolved暂时是null。间接的通过使用相同的Type和TypeProvider作为参数使用另一构造函数实例化一个临时的对象,因为这个构造函数可以生成resolved,再将resolved赋值给 resultType。那为啥不直接使用后者实例化对象呢,因为后者需要一个hashcode,而前者可以生成hashcode。

生成hashCode。

    private int calculateHashCode() {
       int hashCode = ObjectUtils.nullSafeHashCode(this.type);
       if (this.typeProvider != null) {
          hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.typeProvider.getType());
       }
       if (this.variableResolver != null) {
          hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.variableResolver.getSource());
       }
       if (this.componentType != null) {
          hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.componentType);
       }
       return hashCode;
    }

生成resolved。

    private Class<?> resolveClass() {
       if (this.type == EmptyType.INSTANCE) {
          return null;
       }
       if (this.type instanceof Class) {
          return (Class<?>) this.type;
       }
       if (this.type instanceof GenericArrayType) {
          Class<?> resolvedComponent = getComponentType().resolve();
          return (resolvedComponent != null ? Array.newInstance(resolvedComponent, 0).getClass() : null);
       }
       return resolveType().resolve();
    }
    ResolvableType resolveType() {
       if (this.type instanceof ParameterizedType) {
          return forType(((ParameterizedType) this.type).getRawType(), this.variableResolver);
       }
       if (this.type instanceof WildcardType) {
          Type resolved = resolveBounds(((WildcardType) this.type).getUpperBounds());
          if (resolved == null) {
             resolved = resolveBounds(((WildcardType) this.type).getLowerBounds());
          }
          return forType(resolved, this.variableResolver);
       }
       if (this.type instanceof TypeVariable) {
          TypeVariable<?> variable = (TypeVariable<?>) this.type;
          // Try default variable resolution
          if (this.variableResolver != null) {
             ResolvableType resolved = this.variableResolver.resolveVariable(variable);
             if (resolved != null) {
                return resolved;
             }
          }
          // Fallback to bounds
          return forType(resolveBounds(variable.getBounds()), this.variableResolver);
       }
       return NONE;
    }

resolveClass()方法的目的就是将type转换成相关的Class对象,因为只有满足type instanceof Class才返回,否则继续调用forType()递归上面的代码。

ResolvableType还有一个as方法,功能是沿着继承链向上查找参数指定的ResolvableType。

    public ResolvableType as(Class<?> type) {
       if (this == NONE) {
          return NONE;
       }
       if (ObjectUtils.nullSafeEquals(resolve(), type)) {
          return this;
       }
       for (ResolvableType interfaceType : getInterfaces()) {
          ResolvableType interfaceAsType = interfaceType.as(type);
          if (interfaceAsType != NONE) {
             return interfaceAsType;
          }
       }
       return getSuperType().as(type);
    }

下面看看文章开头提及的getSuperType()方法。

    public ResolvableType getSuperType() {
       Class<?> resolved = resolve();
       if (resolved == null || resolved.getGenericSuperclass() == null) {
          return NONE;
       }
       ResolvableType superType = this.superType;
       if (superType == null) {
          superType = forType(SerializableTypeWrapper.forGenericSuperclass(resolved), asVariableResolver());
          this.superType = superType;
       }
       return superType;
    }

SerializableTypeWrapper.forGenericSuperclass(resolved)方法返回当前Class对象父类的可序列化的Type对象,asVariableResolver返回一个DefaultVariableResolver对象,它的resolveVariable()方法用于将TypeVariable转化成 ResolvableType对象,这个类会在isAssignableFrom()方法用到。

    private class DefaultVariableResolver implements VariableResolver {
       @Override
       @Nullable
       public ResolvableType resolveVariable(TypeVariable<?> variable) {
          return ResolvableType.this.resolveVariable(variable);
       }
       @Override
       public Object getSource() {
          return ResolvableType.this;
       }
    }

来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » 【Spring源码分析】06-ResolvableType

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏