Spring源码---ResolvableType整理(spring类型转换准备)

现在来了解这个类的大体作用,需要通过了解在前一章说的关于Type的概念(GenericArrayType.class, ParameterizedType.class, TypeVariable.class, WildcardType.class, Class)

这个类就是将Class、Field、Method等这些描叙为ResolvableType(描叙为Type):例如这些以for开头的方法

   

我们看下Field转换:

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

这里会将Filed的属性设置到FieldTypeProvider(类型提供者)(如果要转换的直接是class就不会有TypeProvider,因为其有实现Type接口):

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;
   }
}

interface TypeProvider extends Serializable {
   @Nullable
   Type getType();
   @Nullable
   default Object getSource() {
      return null;
   }
}

将MethodParameter的属性是设置到:MethodParameterTypeProvider(都实现了TypeProvider 接口)

static class MethodParameterTypeProvider implements TypeProvider {
   @Nullable
   private final String methodName;
   private final Class<?>[] parameterTypes;
   private final Class<?> declaringClass;
   private final int parameterIndex;
   private transient MethodParameter methodParameter;
   @Override
   public Type getType() {
      return this.methodParameter.getGenericParameterType();
   }
    @Override
   public Object getSource() {
      return this.methodParameter;
   }
}

现在看下MethodParameter ,其用来描叙Mehtod的形参的。我们通过spring源码中一个demo来简单了解下:

public int method(String p1, long p2) {
   return 42;
}
public class MethodParameterTests {
   private Method method;
   private MethodParameter stringParameter;
   private MethodParameter longParameter;
   private MethodParameter intReturnType;
   @Before
   public void setUp() throws NoSuchMethodException {
      method = getClass().getMethod("method", String.class, Long.TYPE);
      stringParameter = new MethodParameter(method, 0);
      longParameter = new MethodParameter(method, 1);
      intReturnType = new MethodParameter(method, -1);
   }
}

这里的MethodParameter(method, 0),0表示的就是其是用于描叙该方法的第一个入参。

@Test
public void testEquals() throws NoSuchMethodException {
   Class<?> stringParameterType = stringParameter.getParameterType();
   Class<?> longParameterType = longParameter.getParameterType();
   Class<?> returnParameterType = intReturnType.getParameterType();
}

不过不管是Filed、Method等,其最终的转换方法都是:

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

 

现在先来看下其的各个成员变量描叙的是什么(再来看这个forType方法比较好理解):

public class ResolvableType implements Serializable {
    public static final ResolvableType NONE;
    private static final ResolvableType[] EMPTY_TYPES_ARRAY;
    private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType> cache;
    private final Type type;
    @Nullable
    private final TypeProvider typeProvider;

    @Nullable
    The {@code VariableResolver} to use or {@code null} if no resolver is available.
    private final ResolvableType.VariableResolver variableResolver;
    @Nullable
    private final ResolvableType componentType;
    @Nullable
    private final Integer hash;
    @Nullable
    private Class<?> resolved;
    @Nullable
    private volatile ResolvableType superType;
    @Nullable
    private volatile ResolvableType[] interfaces;
    @Nullable
    private volatile ResolvableType[] generics;

}

1、cache:这个等下结合forType方法来讲。

2、type(必需的属性):这个就是将Class、Field等其本身描叙为Type。

3、typeProvider:类型提供者,就像前面Filed的forField那样,其是填充Field、Method这些的属性。

4、variableResolver:这个通过其注释是用来补充resolved的(看了下,在spring对其使用的过程中一般这个为空)。

interface VariableResolver extends Serializable {

   /**
    * Return the source of the resolver (used for hashCode and equals).
    */
   Object getSource();

   /**
    * Resolve the specified variable.
    * @param variable the variable to resolve
    * @return the resolved variable, or {@code null} if not found
    */
   @Nullable
   ResolvableType resolveVariable(TypeVariable<?> variable);
}

     5、componentType、这个我们看下其的获取(Spring对其的使用并没有主动设置这个值,这个ResolvableType 可以算是一个工具类,可能是给使用者拓展使用,到时候看spring是怎样使用这个属性的,现在并没有在spring中找到是怎样使用的,要调用这个方法也是用的下面那两个判断去获取的)。

public ResolvableType getComponentType() {
   if (this == NONE) {
      return NONE;
   }
   if (this.componentType != null) {
      return this.componentType;
   }
   if (this.type instanceof Class) {
      Class<?> componentType = ((Class<?>) this.type).getComponentType();
      return forType(componentType, this.variableResolver);
   }
   if (this.type instanceof GenericArrayType) {
      return forType(((GenericArrayType) this.type).getGenericComponentType(), this.variableResolver);
   }
   return resolveType().getComponentType();
}

6、superType:这个就是表示要描叙的类型继承的类,可知其是给Class使用的,我们看其的获取

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;
}
@Nullable
VariableResolver asVariableResolver() {
   if (this == NONE) {
      return null;
   }
   return new DefaultVariableResolver();
}

这里最开始是null(spring并没有直接设置其的值),而是获取的时候通过resolved类在通过forType方法,获取该类继承类的Type描叙,再同步到this.superType 。(SerializableTypeWrapper类及方法后面再讲)。

7、interfaces:同上面,就是描叙其上面的接口:

public ResolvableType[] getInterfaces() {
   Class<?> resolved = resolve();
   if (resolved == null || ObjectUtils.isEmpty(resolved.getGenericInterfaces())) {
      return EMPTY_TYPES_ARRAY;
   }
   ResolvableType[] interfaces = this.interfaces;
   if (interfaces == null) {
      interfaces = forTypes(SerializableTypeWrapper.forGenericInterfaces(resolved), asVariableResolver());
      this.interfaces = interfaces;
   }
   return interfaces;
}

8、generics:这个就是描叙泛型的参数,简单来说就是List<XXX>,用来描叙xxx的。通过一个简单的例子来说明

                   public List<Integer> stringListList2;

                            

9、cache:可以看到这个cache是放ResolvableType类型的,我们看其初始化:

private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType> cache =
      new ConcurrentReferenceHashMap<>(256);

可以看到其是与当前Class绑定的全局变量,同时为了并发问题用到是ConcurrentReferenceHashMap。其的put方法的调用我们要看下面的的内容

10、resolved类型:要讲这个成员变量,需要回到前面的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;
   }
   if (type instanceof Class) {
      return new ResolvableType(type, typeProvider, variableResolver, (ResolvableType) null);
   }
        ................
   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不为空,例如Field:

     SerializableTypeWrapper.forTypeProvider(typeProvider);

 private static final Class<?>[] SUPPORTED_SERIALIZABLE_TYPES = {
      GenericArrayType.class, ParameterizedType.class, TypeVariable.class, WildcardType.class};
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());
}

这里先获取TypeProvider的Type类型(对应TypeProvider的实现类,例如Field的、Method的Type):

       

@Override
public Type getType() {
   return this.field.getGenericType();
}
@Override
@Nullable
public Type getType() {
   Object result = this.result;
   if (result == null) {
      // Lazy invocation of the target method on the provided type
      result = ReflectionUtils.invokeMethod(this.method, this.provider.getType());
      // Cache the result for further calls to getType()
      this.result = result;
   }
   return (result instanceof Type[] ? ((Type[]) result)[this.index] : (Type) result);
}
@Override
public Type getType() {
   return this.methodParameter.getGenericParameterType();
}

如果不是序列化的,例如描叙Fied、Method,就会来到SUPPORTED_SERIALIZABLE_TYPES循环,看当前的Type是哪种类型,然后通过动态代理产生一个Type类型的代理对象。TypeProxyInvocationHandler的invoke方法:

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;
      }
      ............
         return method.invoke(this.provider.getType(), args);
      .........
}

现在再回到forType方法:

这里我们先看下ResolvableType的构造方法:

private ResolvableType(
      Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) {

   this.type = type;
   this.typeProvider = typeProvider;
   this.variableResolver = variableResolver;
   this.componentType = null;
   this.hash = calculateHashCode();
   this.resolved = null;
}
private ResolvableType(Type type, @Nullable TypeProvider typeProvider,
      @Nullable VariableResolver variableResolver, @Nullable Integer hash) {

   this.type = type;
   this.typeProvider = typeProvider;
   this.variableResolver = variableResolver;
   this.componentType = null;
   this.hash = hash;
   this.resolved = resolveClass();
}
private ResolvableType(Type type, @Nullable TypeProvider typeProvider,
      @Nullable VariableResolver variableResolver, @Nullable ResolvableType componentType) {

   this.type = type;
   this.typeProvider = typeProvider;
   this.variableResolver = variableResolver;
   this.componentType = componentType;
   this.hash = null;
   this.resolved = resolveClass();
}

  如果当前Type类型就是Class,而不是其他的四种Type则直接创建ResolveType返回,如果不是:

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);
}

这里就是cache的put的地方,首先这里是solvableType(type, typeProvider, variableResolver)实例化一个对象,如果获取不到,再通过ResolvableType(type, typeProvider, variableResolver, resultType.hash)去实例化一个,并放到cache中。这里单看我们会觉得为什么要多此一举,直接通过ResolvableType(type, typeProvider, variableResolver, resultType.hash)创建放到cache中就可以了,之后也再通过ResolvableType(type, typeProvider, variableResolver, resultType.hash)直接创建获取就可以了。要明白这里,我们先看下ResolvableType的equals方法:

@Override
public boolean equals(Object other) {
   ................
   if (this.typeProvider != otherType.typeProvider &&.................) {
      return false;
   }
   if (this.variableResolver != otherType.variableResolver &&............) {
      return false;
   }
   if (!ObjectUtils.nullSafeEquals(this.componentType, otherType.componentType)) {
      return false;
   }
   return true;
}

可以看到这里只比较了ResolvableType的typeProvider、variableResolver、componentType。所以两种构造方法产生的对象并不影响其比较,现在来看下两个构造方法的具体比较:

   其主要是后面ResolvableType(type, typeProvider, variableResolver, resultType.hash)创建的

this.resolved = resolveClass()是通过resolveClass()来赋值的:

@Nullable
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();
}

这里为了简单表明这里的逻辑,我们假设当前描叙的Filed的Type是ParameterizedType:其走到就是下面这个 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;
}

接着走的是forType(((ParameterizedType) this.type).getRawType(), this.variableResolver),可以看到这里又调了forType方法去创建ResolvableType 了。可以看到这里就产生了一个循环获取ResolvableType (所以为了不再走这些重复的并且放到cache中的内容,所以spring先是通过简单的构造函数创建一个对象去cache中获取),这个跳出循环就是type为不为Class。

这里我们再回到前面:

if (cachedType == null) {

        cachedType = new ResolvableType(type, typeProvider, variableResolver, resultType.hash);

        cache.put(cachedType,    cachedType);

}

看下cache的内容:

        public List<Set<Map<String,Integer>>> stringListList3;

        ResolvableType type = ResolvableType.forField(Fields.class.getField("stringListList3")).asCollection();

        

   

    可以看到这里就是放最外层List<XXX>中的XXX的,将其XXX再拆分成E<C>这种,然后在拆分C,将其放到cache中,再由于cache其是全局变量,所以渐渐其就包含了项目中所有例如Class、Field、Method这些的ResolvableType。

    但这里有个地方不明白。例如这里要拆分为List<XXX>、Set<XXX>、最里面是Map<XXX>,但debug的时候我只看到了cache.put使用一次,就是最外面一层List<XXX>的时候put了一次。关于Set<XXX>、Map<XXX>一直没有看到其有使用put添加,但就是已经在cache了,这个地方还不知道是为什么。

     

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值