Introduce ResolvableType.toClass() shortcut

Issue: SPR-17086
This commit is contained in:
Juergen Hoeller 2018-07-25 14:15:19 +02:00
parent 31bfc1dc2b
commit fd8e4abe5d
26 changed files with 40 additions and 28 deletions

View File

@ -159,12 +159,12 @@ public final class BridgeMethodResolver {
Class<?> candidateParameter = candidateParameters[i];
if (candidateParameter.isArray()) {
// An array type: compare the component type.
if (!candidateParameter.getComponentType().equals(genericParameter.getComponentType().resolve(Object.class))) {
if (!candidateParameter.getComponentType().equals(genericParameter.getComponentType().toClass())) {
return false;
}
}
// A non-array type: compare the type itself.
if (!candidateParameter.equals(genericParameter.resolve(Object.class))) {
if (!candidateParameter.equals(genericParameter.toClass())) {
return false;
}
}

View File

@ -212,7 +212,7 @@ public final class Conventions {
ReactiveAdapter adapter = reactiveAdapterRegistry.getAdapter(valueClass);
if (adapter != null && !adapter.getDescriptor().isNoValue()) {
reactiveSuffix = ClassUtils.getShortName(valueClass);
valueClass = ResolvableType.forMethodReturnType(method).getGeneric().resolve(Object.class);
valueClass = ResolvableType.forMethodReturnType(method).getGeneric().toClass();
}
}
}

View File

@ -229,7 +229,7 @@ public final class GenericTypeResolver {
*/
@SuppressWarnings("rawtypes")
public static Class<?> resolveType(Type genericType, Map<TypeVariable, Type> map) {
return ResolvableType.forType(genericType, new TypeVariableMapVariableResolver(map)).resolve(Object.class);
return ResolvableType.forType(genericType, new TypeVariableMapVariableResolver(map)).toClass();
}
/**

View File

@ -229,6 +229,18 @@ public class ResolvableType implements Serializable {
return (source != null ? source : this.type);
}
/**
* Return this type as a resolved {@code Class}, falling back to
* {@link java.lang.Object} if no specific class can be resolved.
* @return the resolved {@link Class} or the {@code Object} fallback
* @since 5.1
* @see #getRawClass()
* @see #resolve(Class)
*/
public Class<?> toClass() {
return resolve(Object.class);
}
/**
* Determine whether the given object is an instance of this {@code ResolvableType}.
* @param obj the object to check
@ -328,7 +340,7 @@ public class ResolvableType implements Serializable {
if (ourResolved == null) {
ourResolved = resolve(Object.class);
}
Class<?> otherResolved = other.resolve(Object.class);
Class<?> otherResolved = other.toClass();
// We need an exact type match for generics
// List<CharSequence> is not assignable from List<String>

View File

@ -43,7 +43,7 @@ public class ByteArrayEncoder extends AbstractEncoder<byte[]> {
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.resolve(Object.class);
Class<?> clazz = elementType.toClass();
return super.canEncode(elementType, mimeType) && byte[].class.isAssignableFrom(clazz);
}

View File

@ -44,7 +44,7 @@ public class ByteBufferEncoder extends AbstractEncoder<ByteBuffer> {
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.resolve(Object.class);
Class<?> clazz = elementType.toClass();
return super.canEncode(elementType, mimeType) && ByteBuffer.class.isAssignableFrom(clazz);
}

View File

@ -56,7 +56,7 @@ public final class CharSequenceEncoder extends AbstractEncoder<CharSequence> {
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.resolve(Object.class);
Class<?> clazz = elementType.toClass();
return super.canEncode(elementType, mimeType) && CharSequence.class.isAssignableFrom(clazz);
}

View File

@ -43,7 +43,7 @@ public class DataBufferEncoder extends AbstractEncoder<DataBuffer> {
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.resolve(Object.class);
Class<?> clazz = elementType.toClass();
return super.canEncode(elementType, mimeType) && DataBuffer.class.isAssignableFrom(clazz);
}

View File

@ -60,7 +60,7 @@ public class ResourceEncoder extends AbstractSingleValueEncoder<Resource> {
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.resolve(Object.class);
Class<?> clazz = elementType.toClass();
return (super.canEncode(elementType, mimeType) && Resource.class.isAssignableFrom(clazz));
}

View File

@ -73,7 +73,7 @@ public class ResourceRegionEncoder extends AbstractEncoder<ResourceRegion> {
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
return super.canEncode(elementType, mimeType)
&& ResourceRegion.class.isAssignableFrom(elementType.resolve(Object.class));
&& ResourceRegion.class.isAssignableFrom(elementType.toClass());
}
@Override

View File

@ -120,7 +120,7 @@ public class TypeDescriptor implements Serializable {
*/
protected TypeDescriptor(ResolvableType resolvableType, @Nullable Class<?> type, @Nullable Annotation[] annotations) {
this.resolvableType = resolvableType;
this.type = (type != null ? type : resolvableType.resolve(Object.class));
this.type = (type != null ? type : resolvableType.toClass());
this.annotatedElement = new AnnotatedElementAdapter(annotations);
}

View File

@ -117,7 +117,7 @@ public class GenericConversionService implements ConfigurableConversionService {
"ConverterFactory [" + factory.getClass().getName() + "]; does the class parameterize those types?");
}
addConverter(new ConverterFactoryAdapter(factory,
new ConvertiblePair(typeInfo[0].resolve(Object.class), typeInfo[1].resolve(Object.class))));
new ConvertiblePair(typeInfo[0].toClass(), typeInfo[1].toClass())));
}
@Override
@ -351,7 +351,7 @@ public class GenericConversionService implements ConfigurableConversionService {
public ConverterAdapter(Converter<?, ?> converter, ResolvableType sourceType, ResolvableType targetType) {
this.converter = (Converter<Object, Object>) converter;
this.typeInfo = new ConvertiblePair(sourceType.resolve(Object.class), targetType.resolve(Object.class));
this.typeInfo = new ConvertiblePair(sourceType.toClass(), targetType.toClass());
this.targetType = targetType;
}

View File

@ -619,7 +619,7 @@ public class ResolvableTypeTests {
ResolvableType type = ResolvableType.forField(Fields.class.getField("variableTypeGenericArray"));
assertThat(type.getType().toString(), equalTo("T[]"));
assertThat(type.isArray(), equalTo(true));
assertThat(type.resolve(Object.class), equalTo((Class) Object.class));
assertThat(type.toClass(), equalTo((Class) Object.class));
}
@Test

View File

@ -97,7 +97,7 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol
private Class<?> getPayloadType(MethodParameter parameter) {
Type genericParamType = parameter.getGenericParameterType();
ResolvableType resolvableType = ResolvableType.forType(genericParamType).as(Message.class);
return resolvableType.getGeneric().resolve(Object.class);
return resolvableType.getGeneric().toClass();
}
/**

View File

@ -282,7 +282,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
return this.returnValue.getClass();
}
if (!ResolvableType.NONE.equals(this.returnType)) {
return this.returnType.resolve(Object.class);
return this.returnType.toClass();
}
return super.getParameterType();
}

View File

@ -84,7 +84,7 @@ public class FormHttpMessageReader extends LoggingCodecSupport
public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType) {
return ((MULTIVALUE_TYPE.isAssignableFrom(elementType) ||
(elementType.hasUnresolvableGenerics() &&
MultiValueMap.class.isAssignableFrom(elementType.resolve(Object.class)))) &&
MultiValueMap.class.isAssignableFrom(elementType.toClass()))) &&
(mediaType == null || MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType)));
}

View File

@ -93,7 +93,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
@Override
public boolean canWrite(ResolvableType elementType, @Nullable MediaType mediaType) {
return (mediaType == null || MediaType.TEXT_EVENT_STREAM.includes(mediaType) ||
ServerSentEvent.class.isAssignableFrom(elementType.resolve(Object.class)));
ServerSentEvent.class.isAssignableFrom(elementType.toClass()));
}
@Override

View File

@ -68,7 +68,7 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
JavaType javaType = getObjectMapper().getTypeFactory().constructType(elementType.getType());
// Skip String: CharSequenceDecoder + "*/*" comes after
return (!CharSequence.class.isAssignableFrom(elementType.resolve(Object.class)) &&
return (!CharSequence.class.isAssignableFrom(elementType.toClass()) &&
getObjectMapper().canDeserialize(javaType) && supportsMimeType(mimeType));
}

View File

@ -100,7 +100,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.resolve(Object.class);
Class<?> clazz = elementType.toClass();
return supportsMimeType(mimeType) && (Object.class == clazz ||
(!String.class.isAssignableFrom(elementType.resolve(clazz)) && getObjectMapper().canSerialize(clazz)));
}

View File

@ -86,7 +86,7 @@ public class SynchronossPartHttpMessageReader extends LoggingCodecSupport implem
@Override
public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType) {
return Part.class.equals(elementType.resolve(Object.class)) &&
return Part.class.equals(elementType.toClass()) &&
(mediaType == null || MediaType.MULTIPART_FORM_DATA.isCompatibleWith(mediaType));
}

View File

@ -60,7 +60,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
if (super.canEncode(elementType, mimeType)) {
Class<?> outputClass = elementType.resolve(Object.class);
Class<?> outputClass = elementType.toClass();
return (outputClass.isAnnotationPresent(XmlRootElement.class) ||
outputClass.isAnnotationPresent(XmlType.class));
}

View File

@ -89,7 +89,7 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand
}
ReactiveAdapter adapter = getAdapter(result);
return adapter != null && !adapter.isNoValue() &&
isSupportedType(result.getReturnType().getGeneric().resolve(Object.class));
isSupportedType(result.getReturnType().getGeneric().toClass());
}
@Nullable

View File

@ -157,7 +157,7 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport
if (adapter.isNoValue()) {
return true;
}
type = result.getReturnType().getGeneric().resolve(Object.class);
type = result.getReturnType().getGeneric().toClass();
}
return (type != null &&

View File

@ -288,7 +288,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
else {
Type type = getHttpEntityType(returnType);
type = (type != null ? type : Object.class);
return ResolvableType.forMethodParameter(returnType, type).resolve(Object.class);
return ResolvableType.forMethodParameter(returnType, type).toClass();
}
}

View File

@ -123,7 +123,7 @@ class ReactiveTypeHandler {
Assert.state(adapter != null, "Unexpected return value: " + returnValue);
ResolvableType elementType = ResolvableType.forMethodParameter(returnType).getGeneric();
Class<?> elementClass = elementType.resolve(Object.class);
Class<?> elementClass = elementType.toClass();
Collection<MediaType> mediaTypes = getMediaTypes(request);
Optional<MediaType> mediaType = mediaTypes.stream().filter(MimeType::isConcrete).findFirst();

View File

@ -271,7 +271,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
return this.returnValue.getClass();
}
if (!ResolvableType.NONE.equals(this.returnType)) {
return this.returnType.resolve(Object.class);
return this.returnType.toClass();
}
return super.getParameterType();
}