ResolvableType returns clone for cached state with original local source
Issue: SPR-16210
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -117,36 +117,35 @@ public class ResolvableType implements Serializable {
|
||||
@Nullable
|
||||
private final ResolvableType componentType;
|
||||
|
||||
/**
|
||||
* Copy of the resolved value.
|
||||
*/
|
||||
@Nullable
|
||||
private final Class<?> resolved;
|
||||
|
||||
@Nullable
|
||||
private final Integer hash;
|
||||
|
||||
@Nullable
|
||||
private ResolvableType superType;
|
||||
private Class<?> resolved;
|
||||
|
||||
@Nullable
|
||||
private ResolvableType[] interfaces;
|
||||
private volatile ResolvableType superType;
|
||||
|
||||
@Nullable
|
||||
private ResolvableType[] generics;
|
||||
private volatile ResolvableType[] interfaces;
|
||||
|
||||
@Nullable
|
||||
private volatile ResolvableType[] generics;
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor used to create a new {@link ResolvableType} for cache key purposes,
|
||||
* with no upfront resolution.
|
||||
*/
|
||||
private ResolvableType(Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) {
|
||||
private ResolvableType(
|
||||
Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) {
|
||||
|
||||
this.type = type;
|
||||
this.typeProvider = typeProvider;
|
||||
this.variableResolver = variableResolver;
|
||||
this.componentType = null;
|
||||
this.resolved = null;
|
||||
this.hash = calculateHashCode();
|
||||
this.resolved = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,8 +160,8 @@ public class ResolvableType implements Serializable {
|
||||
this.typeProvider = typeProvider;
|
||||
this.variableResolver = variableResolver;
|
||||
this.componentType = null;
|
||||
this.resolved = resolveClass();
|
||||
this.hash = hash;
|
||||
this.resolved = resolveClass();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,8 +175,8 @@ public class ResolvableType implements Serializable {
|
||||
this.typeProvider = typeProvider;
|
||||
this.variableResolver = variableResolver;
|
||||
this.componentType = componentType;
|
||||
this.resolved = resolveClass();
|
||||
this.hash = null;
|
||||
this.resolved = resolveClass();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,10 +452,12 @@ public class ResolvableType implements Serializable {
|
||||
if (resolved == null || resolved.getGenericSuperclass() == null) {
|
||||
return NONE;
|
||||
}
|
||||
if (this.superType == null) {
|
||||
this.superType = forType(SerializableTypeWrapper.forGenericSuperclass(resolved), asVariableResolver());
|
||||
ResolvableType superType = this.superType;
|
||||
if (superType == null) {
|
||||
superType = forType(SerializableTypeWrapper.forGenericSuperclass(resolved), asVariableResolver());
|
||||
this.superType = superType;
|
||||
}
|
||||
return this.superType;
|
||||
return superType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -470,10 +471,12 @@ public class ResolvableType implements Serializable {
|
||||
if (resolved == null || ObjectUtils.isEmpty(resolved.getGenericInterfaces())) {
|
||||
return EMPTY_TYPES_ARRAY;
|
||||
}
|
||||
if (this.interfaces == null) {
|
||||
this.interfaces = forTypes(SerializableTypeWrapper.forGenericInterfaces(resolved), asVariableResolver());
|
||||
ResolvableType[] interfaces = this.interfaces;
|
||||
if (interfaces == null) {
|
||||
interfaces = forTypes(SerializableTypeWrapper.forGenericInterfaces(resolved), asVariableResolver());
|
||||
this.interfaces = interfaces;
|
||||
}
|
||||
return this.interfaces;
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -667,24 +670,25 @@ public class ResolvableType implements Serializable {
|
||||
if (this == NONE) {
|
||||
return EMPTY_TYPES_ARRAY;
|
||||
}
|
||||
if (this.generics == null) {
|
||||
ResolvableType[] generics = this.generics;
|
||||
if (generics == null) {
|
||||
if (this.type instanceof Class) {
|
||||
Class<?> typeClass = (Class<?>) this.type;
|
||||
this.generics = forTypes(SerializableTypeWrapper.forTypeParameters(typeClass), this.variableResolver);
|
||||
generics = forTypes(SerializableTypeWrapper.forTypeParameters(typeClass), this.variableResolver);
|
||||
}
|
||||
else if (this.type instanceof ParameterizedType) {
|
||||
Type[] actualTypeArguments = ((ParameterizedType) this.type).getActualTypeArguments();
|
||||
ResolvableType[] generics = new ResolvableType[actualTypeArguments.length];
|
||||
generics = new ResolvableType[actualTypeArguments.length];
|
||||
for (int i = 0; i < actualTypeArguments.length; i++) {
|
||||
generics[i] = forType(actualTypeArguments[i], this.variableResolver);
|
||||
}
|
||||
this.generics = generics;
|
||||
}
|
||||
else {
|
||||
this.generics = resolveType().getGenerics();
|
||||
generics = resolveType().getGenerics();
|
||||
}
|
||||
this.generics = generics;
|
||||
}
|
||||
return this.generics;
|
||||
return generics;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -748,7 +752,7 @@ public class ResolvableType implements Serializable {
|
||||
*/
|
||||
@Nullable
|
||||
public Class<?> resolve() {
|
||||
return (this.resolved != null ? this.resolved : null);
|
||||
return this.resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1372,7 +1376,9 @@ public class ResolvableType implements Serializable {
|
||||
* @param variableResolver the variable resolver or {@code null}
|
||||
* @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver}
|
||||
*/
|
||||
static ResolvableType forType(@Nullable Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) {
|
||||
static ResolvableType forType(
|
||||
@Nullable Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) {
|
||||
|
||||
if (type == null && typeProvider != null) {
|
||||
type = SerializableTypeWrapper.forTypeProvider(typeProvider);
|
||||
}
|
||||
@@ -1390,13 +1396,14 @@ public class ResolvableType implements Serializable {
|
||||
cache.purgeUnreferencedEntries();
|
||||
|
||||
// Check the cache - we may have a ResolvableType which has been resolved before...
|
||||
ResolvableType key = new ResolvableType(type, typeProvider, variableResolver);
|
||||
ResolvableType resolvableType = cache.get(key);
|
||||
if (resolvableType == null) {
|
||||
resolvableType = new ResolvableType(type, typeProvider, variableResolver, key.hash);
|
||||
cache.put(resolvableType, resolvableType);
|
||||
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);
|
||||
}
|
||||
return resolvableType;
|
||||
resultType.resolved = cachedType.resolved;
|
||||
return resultType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user