From fd8e4abe5d5d55cf4910c2745eed2e9b4963fcec Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Jul 2018 14:15:19 +0200 Subject: [PATCH] Introduce ResolvableType.toClass() shortcut Issue: SPR-17086 --- .../springframework/core/BridgeMethodResolver.java | 4 ++-- .../java/org/springframework/core/Conventions.java | 2 +- .../springframework/core/GenericTypeResolver.java | 2 +- .../org/springframework/core/ResolvableType.java | 14 +++++++++++++- .../core/codec/ByteArrayEncoder.java | 2 +- .../core/codec/ByteBufferEncoder.java | 2 +- .../core/codec/CharSequenceEncoder.java | 2 +- .../core/codec/DataBufferEncoder.java | 2 +- .../core/codec/ResourceEncoder.java | 2 +- .../core/codec/ResourceRegionEncoder.java | 2 +- .../core/convert/TypeDescriptor.java | 2 +- .../convert/support/GenericConversionService.java | 4 ++-- .../springframework/core/ResolvableTypeTests.java | 2 +- .../support/MessageMethodArgumentResolver.java | 2 +- .../handler/invocation/InvocableHandlerMethod.java | 2 +- .../http/codec/FormHttpMessageReader.java | 2 +- .../codec/ServerSentEventHttpMessageWriter.java | 2 +- .../http/codec/json/AbstractJackson2Decoder.java | 2 +- .../http/codec/json/AbstractJackson2Encoder.java | 2 +- .../SynchronossPartHttpMessageReader.java | 2 +- .../http/codec/xml/Jaxb2XmlEncoder.java | 2 +- .../annotation/ResponseEntityResultHandler.java | 2 +- .../result/view/ViewResolutionResultHandler.java | 2 +- .../annotation/HttpEntityMethodProcessor.java | 2 +- .../mvc/method/annotation/ReactiveTypeHandler.java | 2 +- .../annotation/ServletInvocableHandlerMethod.java | 2 +- 26 files changed, 40 insertions(+), 28 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java b/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java index e1c1d7b89c..a10c8f1328 100644 --- a/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java +++ b/spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java @@ -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; } } diff --git a/spring-core/src/main/java/org/springframework/core/Conventions.java b/spring-core/src/main/java/org/springframework/core/Conventions.java index e6191747ec..1f9bdf0212 100644 --- a/spring-core/src/main/java/org/springframework/core/Conventions.java +++ b/spring-core/src/main/java/org/springframework/core/Conventions.java @@ -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(); } } } diff --git a/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java b/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java index 307bd502b4..672130088b 100644 --- a/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java +++ b/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java @@ -229,7 +229,7 @@ public final class GenericTypeResolver { */ @SuppressWarnings("rawtypes") public static Class resolveType(Type genericType, Map map) { - return ResolvableType.forType(genericType, new TypeVariableMapVariableResolver(map)).resolve(Object.class); + return ResolvableType.forType(genericType, new TypeVariableMapVariableResolver(map)).toClass(); } /** diff --git a/spring-core/src/main/java/org/springframework/core/ResolvableType.java b/spring-core/src/main/java/org/springframework/core/ResolvableType.java index 0381967b58..3e076f8945 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -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 is not assignable from List diff --git a/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java index d10f3c4824..8525b3fbe6 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java @@ -43,7 +43,7 @@ public class ByteArrayEncoder extends AbstractEncoder { @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); } diff --git a/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java index 4d3626a87a..d90ea44b22 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java @@ -44,7 +44,7 @@ public class ByteBufferEncoder extends AbstractEncoder { @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); } diff --git a/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java index a6189d4a38..d5eb62906e 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java @@ -56,7 +56,7 @@ public final class CharSequenceEncoder extends AbstractEncoder { @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); } diff --git a/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java index d616deb290..b5b113e5f1 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java @@ -43,7 +43,7 @@ public class DataBufferEncoder extends AbstractEncoder { @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); } diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java index 94ce722107..0ea264acdb 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java @@ -60,7 +60,7 @@ public class ResourceEncoder extends AbstractSingleValueEncoder { @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)); } diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java index 3d5012160e..80bbef8ef7 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java @@ -73,7 +73,7 @@ public class ResourceRegionEncoder extends AbstractEncoder { @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 diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index 42cbccb14e..9dfcbad236 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -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); } diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java index 3ee029c269..4019283691 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java @@ -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) converter; - this.typeInfo = new ConvertiblePair(sourceType.resolve(Object.class), targetType.resolve(Object.class)); + this.typeInfo = new ConvertiblePair(sourceType.toClass(), targetType.toClass()); this.targetType = targetType; } diff --git a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java index 3dde706f04..5e46f80d12 100644 --- a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java +++ b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java @@ -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 diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java index 8a337715a5..d92af195ae 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java @@ -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(); } /** diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java index 45318328e0..af36e8d6a4 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java @@ -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(); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java index 76a47fde57..3d6e0abca1 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java @@ -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))); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java index 61e272e4cf..fca24aed74 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java @@ -93,7 +93,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter clazz = elementType.resolve(Object.class); + Class clazz = elementType.toClass(); return supportsMimeType(mimeType) && (Object.class == clazz || (!String.class.isAssignableFrom(elementType.resolve(clazz)) && getObjectMapper().canSerialize(clazz))); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java index a8a5061da6..c54ce4827f 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java @@ -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)); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java index 0b95a983f2..fc5617848c 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java @@ -60,7 +60,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder { @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)); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java index ac1331969e..59b0b7d29b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java @@ -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 diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index 69d84bd719..04a05f038b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -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 && diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java index 2b0e2f317d..cb91f07d56 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java @@ -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(); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java index 3606c16ef8..dfb4677194 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ReactiveTypeHandler.java @@ -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 mediaTypes = getMediaTypes(request); Optional mediaType = mediaTypes.stream().filter(MimeType::isConcrete).findFirst(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java index 2dcd3e7a1d..7b6af12b12 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java @@ -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(); }