现在来了解这个类的大体作用,需要通过了解在前一章说的关于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了,这个地方还不知道是为什么。