Polishing

This commit is contained in:
Juergen Hoeller 2018-06-29 20:07:53 +02:00
parent 5a111125c1
commit ea534b6820
13 changed files with 42 additions and 51 deletions

View File

@ -45,7 +45,7 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
* @see javax.transaction.Transactional * @see javax.transaction.Transactional
* @see AnnotationTransactionAspect * @see AnnotationTransactionAspect
*/ */
@RequiredTypes({"javax.transaction.Transactional"}) @RequiredTypes("javax.transaction.Transactional")
public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect { public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect {
public JtaAnnotationTransactionAspect() { public JtaAnnotationTransactionAspect() {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -97,7 +97,7 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol
private Class<?> getPayloadType(MethodParameter parameter) { private Class<?> getPayloadType(MethodParameter parameter) {
Type genericParamType = parameter.getGenericParameterType(); Type genericParamType = parameter.getGenericParameterType();
ResolvableType resolvableType = ResolvableType.forType(genericParamType).as(Message.class); ResolvableType resolvableType = ResolvableType.forType(genericParamType).as(Message.class);
return resolvableType.getGeneric(0).resolve(Object.class); return resolvableType.getGeneric().resolve(Object.class);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,6 +36,7 @@ import org.springframework.web.util.UriComponentsBuilder;
/** /**
* Mock implementation of {@link ClientHttpRequest}. * Mock implementation of {@link ClientHttpRequest}.
*
* @author Brian Clozel * @author Brian Clozel
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @since 5.0
@ -97,11 +98,9 @@ public class MockClientHttpRequest extends AbstractClientHttpRequest {
/** /**
* Configure a custom handler for writing the request body. * Configure a custom handler for writing the request body.
*
* <p>The default write handler consumes and caches the request body so it * <p>The default write handler consumes and caches the request body so it
* may be accessed subsequently, e.g. in test assertions. Use this property * may be accessed subsequently, e.g. in test assertions. Use this property
* when the request body is an infinite stream. * when the request body is an infinite stream.
*
* @param writeHandler the write handler to use returning {@code Mono<Void>} * @param writeHandler the write handler to use returning {@code Mono<Void>}
* when the body has been "written" (i.e. consumed). * when the body has been "written" (i.e. consumed).
*/ */

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -125,10 +125,8 @@ public class MockServerHttpResponse extends AbstractServerHttpResponse {
* charset or "UTF-8" by default. * charset or "UTF-8" by default.
*/ */
public Mono<String> getBodyAsString() { public Mono<String> getBodyAsString() {
Charset charset = Optional.ofNullable(getHeaders().getContentType()).map(MimeType::getCharset) Charset charset = Optional.ofNullable(getHeaders().getContentType()).map(MimeType::getCharset)
.orElse(StandardCharsets.UTF_8); .orElse(StandardCharsets.UTF_8);
return getBody() return getBody()
.reduce(bufferFactory().allocateBuffer(), (previous, current) -> { .reduce(bufferFactory().allocateBuffer(), (previous, current) -> {
previous.write(current); previous.write(current);
@ -139,7 +137,6 @@ public class MockServerHttpResponse extends AbstractServerHttpResponse {
} }
private static String bufferToString(DataBuffer buffer, Charset charset) { private static String bufferToString(DataBuffer buffer, Charset charset) {
Assert.notNull(charset, "'charset' must not be null");
byte[] bytes = new byte[buffer.readableByteCount()]; byte[] bytes = new byte[buffer.readableByteCount()];
buffer.read(bytes); buffer.read(bytes);
return new String(bytes, charset); return new String(bytes, charset);

View File

@ -239,13 +239,16 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
/** /**
* Add expectations to this group. * Add expectations to this group.
* @deprecated as of 5.0.3 please use {@link #addAllExpectations(Collection)} instead. * @deprecated as of 5.0.3, if favor of {@link #addAllExpectations}
*/ */
@Deprecated @Deprecated
public void updateAll(Collection<RequestExpectation> expectations) { public void updateAll(Collection<RequestExpectation> expectations) {
expectations.forEach(this::updateInternal); expectations.forEach(this::updateInternal);
} }
/**
* Reset all expectations for this group.
*/
public void reset() { public void reset() {
this.expectations.clear(); this.expectations.clear();
} }

View File

@ -103,7 +103,7 @@ public class ServerSentEventHttpMessageReader implements HttpMessageReader<Objec
Map<String, Object> hints) { Map<String, Object> hints) {
boolean shouldWrap = isServerSentEvent(elementType); boolean shouldWrap = isServerSentEvent(elementType);
ResolvableType valueType = (shouldWrap ? elementType.getGeneric(0) : elementType); ResolvableType valueType = (shouldWrap ? elementType.getGeneric() : elementType);
return stringDecoder.decode(message.getBody(), STRING_TYPE, null, Collections.emptyMap()) return stringDecoder.decode(message.getBody(), STRING_TYPE, null, Collections.emptyMap())
.bufferUntil(line -> line.equals("")) .bufferUntil(line -> line.equals(""))

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -123,7 +123,7 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
ResolvableType elementType; ResolvableType elementType;
if (adapter != null) { if (adapter != null) {
publisher = adapter.toPublisher(body); publisher = adapter.toPublisher(body);
ResolvableType genericType = bodyType.getGeneric(0); ResolvableType genericType = bodyType.getGeneric();
elementType = getElementType(adapter, genericType); elementType = getElementType(adapter, genericType);
} }
else { else {

View File

@ -56,9 +56,9 @@ public abstract class AbstractView implements View, ApplicationContextAware {
private static final Object NO_VALUE = new Object(); private static final Object NO_VALUE = new Object();
private final List<MediaType> mediaTypes = new ArrayList<>(4); private final ReactiveAdapterRegistry reactiveAdapterRegistry;
private final ReactiveAdapterRegistry adapterRegistry; private final List<MediaType> mediaTypes = new ArrayList<>(4);
private Charset defaultCharset = StandardCharsets.UTF_8; private Charset defaultCharset = StandardCharsets.UTF_8;
@ -73,9 +73,9 @@ public abstract class AbstractView implements View, ApplicationContextAware {
this(ReactiveAdapterRegistry.getSharedInstance()); this(ReactiveAdapterRegistry.getSharedInstance());
} }
public AbstractView(ReactiveAdapterRegistry registry) { public AbstractView(ReactiveAdapterRegistry reactiveAdapterRegistry) {
this.reactiveAdapterRegistry = reactiveAdapterRegistry;
this.mediaTypes.add(ViewResolverSupport.DEFAULT_CONTENT_TYPE); this.mediaTypes.add(ViewResolverSupport.DEFAULT_CONTENT_TYPE);
this.adapterRegistry = registry;
} }
@ -155,7 +155,7 @@ public abstract class AbstractView implements View, ApplicationContextAware {
/** /**
* Prepare the model to render. * Prepare the model to render.
* @param model Map with name Strings as keys and corresponding model * @param model a Map with name Strings as keys and corresponding model
* objects as values (Map can also be {@code null} in case of empty model) * objects as values (Map can also be {@code null} in case of empty model)
* @param contentType the content type selected to render with which should * @param contentType the content type selected to render with which should
* match one of the {@link #getSupportedMediaTypes() supported media types}. * match one of the {@link #getSupportedMediaTypes() supported media types}.
@ -209,7 +209,6 @@ public abstract class AbstractView implements View, ApplicationContextAware {
* @return {@code Mono} for the completion of async attributes resolution * @return {@code Mono} for the completion of async attributes resolution
*/ */
protected Mono<Void> resolveAsyncAttributes(Map<String, Object> model) { protected Mono<Void> resolveAsyncAttributes(Map<String, Object> model) {
List<String> names = new ArrayList<>(); List<String> names = new ArrayList<>();
List<Mono<?>> valueMonos = new ArrayList<>(); List<Mono<?>> valueMonos = new ArrayList<>();
@ -218,7 +217,7 @@ public abstract class AbstractView implements View, ApplicationContextAware {
if (value == null) { if (value == null) {
continue; continue;
} }
ReactiveAdapter adapter = this.adapterRegistry.getAdapter(null, value); ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(null, value);
if (adapter != null) { if (adapter != null) {
names.add(entry.getKey()); names.add(entry.getKey());
if (adapter.isMultiValue()) { if (adapter.isMultiValue()) {

View File

@ -35,7 +35,6 @@ import org.springframework.util.ObjectUtils;
public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer
extends AbstractDispatcherHandlerInitializer { extends AbstractDispatcherHandlerInitializer {
/** /**
* {@inheritDoc} * {@inheritDoc}
* <p>This implementation creates an {@link AnnotationConfigApplicationContext}, * <p>This implementation creates an {@link AnnotationConfigApplicationContext},

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -86,9 +86,7 @@ class ReactiveTypeHandler {
this(ReactiveAdapterRegistry.getSharedInstance(), new SyncTaskExecutor(), new ContentNegotiationManager()); this(ReactiveAdapterRegistry.getSharedInstance(), new SyncTaskExecutor(), new ContentNegotiationManager());
} }
ReactiveTypeHandler(ReactiveAdapterRegistry registry, TaskExecutor executor, ReactiveTypeHandler(ReactiveAdapterRegistry registry, TaskExecutor executor, ContentNegotiationManager manager) {
ContentNegotiationManager manager) {
Assert.notNull(registry, "ReactiveAdapterRegistry is required"); Assert.notNull(registry, "ReactiveAdapterRegistry is required");
Assert.notNull(executor, "TaskExecutor is required"); Assert.notNull(executor, "TaskExecutor is required");
Assert.notNull(manager, "ContentNegotiationManager is required"); Assert.notNull(manager, "ContentNegotiationManager is required");
@ -120,7 +118,7 @@ class ReactiveTypeHandler {
ReactiveAdapter adapter = this.reactiveRegistry.getAdapter(returnValue.getClass()); ReactiveAdapter adapter = this.reactiveRegistry.getAdapter(returnValue.getClass());
Assert.state(adapter != null, "Unexpected return value: " + returnValue); Assert.state(adapter != null, "Unexpected return value: " + returnValue);
ResolvableType elementType = ResolvableType.forMethodParameter(returnType).getGeneric(0); ResolvableType elementType = ResolvableType.forMethodParameter(returnType).getGeneric();
Class<?> elementClass = elementType.resolve(Object.class); Class<?> elementClass = elementType.resolve(Object.class);
Collection<MediaType> mediaTypes = getMediaTypes(request); Collection<MediaType> mediaTypes = getMediaTypes(request);
@ -249,7 +247,7 @@ class ReactiveTypeHandler {
schedule(); schedule();
} }
} }
private void schedule() { private void schedule() {
try { try {
this.taskExecutor.execute(this); this.taskExecutor.execute(this);
@ -264,7 +262,7 @@ class ReactiveTypeHandler {
} }
} }
} }
@Override @Override
public void run() { public void run() {
if (this.done) { if (this.done) {
@ -310,7 +308,7 @@ class ReactiveTypeHandler {
} }
return; return;
} }
if (this.executing.decrementAndGet() != 0) { if (this.executing.decrementAndGet() != 0) {
schedule(); schedule();
} }
@ -324,7 +322,6 @@ class ReactiveTypeHandler {
this.subscription.cancel(); this.subscription.cancel();
} }
} }
} }
@ -407,16 +404,12 @@ class ReactiveTypeHandler {
private final CollectedValuesList values; private final CollectedValuesList values;
DeferredResultSubscriber(DeferredResult<Object> result, ReactiveAdapter adapter, ResolvableType elementType) {
DeferredResultSubscriber(DeferredResult<Object> result, ReactiveAdapter adapter,
ResolvableType elementType) {
this.result = result; this.result = result;
this.multiValueSource = adapter.isMultiValue(); this.multiValueSource = adapter.isMultiValue();
this.values = new CollectedValuesList(elementType); this.values = new CollectedValuesList(elementType);
} }
public void connect(ReactiveAdapter adapter, Object returnValue) { public void connect(ReactiveAdapter adapter, Object returnValue) {
Publisher<Object> publisher = adapter.toPublisher(returnValue); Publisher<Object> publisher = adapter.toPublisher(returnValue);
publisher.subscribe(this); publisher.subscribe(this);
@ -452,6 +445,10 @@ class ReactiveTypeHandler {
} }
} }
/**
* List of collect values where all elements are a specified type.
*/
@SuppressWarnings("serial") @SuppressWarnings("serial")
static class CollectedValuesList extends ArrayList<Object> { static class CollectedValuesList extends ArrayList<Object> {
@ -466,4 +463,4 @@ class ReactiveTypeHandler {
} }
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -83,17 +82,14 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
/** /**
* Complete constructor with pluggable "reactive" type support. * Complete constructor with pluggable "reactive" type support.
*
* @param messageConverters converters to write emitted objects with * @param messageConverters converters to write emitted objects with
* @param reactiveRegistry for reactive return value type support * @param reactiveRegistry for reactive return value type support
* @param executor for blocking I/O writes of items emitted from reactive types * @param executor for blocking I/O writes of items emitted from reactive types
* @param manager for detecting streaming media types * @param manager for detecting streaming media types
*
* @since 5.0 * @since 5.0
*/ */
public ResponseBodyEmitterReturnValueHandler(List<HttpMessageConverter<?>> messageConverters, public ResponseBodyEmitterReturnValueHandler(List<HttpMessageConverter<?>> messageConverters,
ReactiveAdapterRegistry reactiveRegistry, TaskExecutor executor, ReactiveAdapterRegistry reactiveRegistry, TaskExecutor executor, ContentNegotiationManager manager) {
ContentNegotiationManager manager) {
Assert.notEmpty(messageConverters, "HttpMessageConverter List must not be empty"); Assert.notEmpty(messageConverters, "HttpMessageConverter List must not be empty");
this.messageConverters = messageConverters; this.messageConverters = messageConverters;
@ -103,16 +99,16 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
@Override @Override
public boolean supportsReturnType(MethodParameter returnType) { public boolean supportsReturnType(MethodParameter returnType) {
Class<?> bodyType = ResponseEntity.class.isAssignableFrom(returnType.getParameterType()) ? Class<?> bodyType = ResponseEntity.class.isAssignableFrom(returnType.getParameterType()) ?
ResolvableType.forMethodParameter(returnType).getGeneric(0).resolve() : ResolvableType.forMethodParameter(returnType).getGeneric().resolve() :
returnType.getParameterType(); returnType.getParameterType();
return bodyType != null && (ResponseBodyEmitter.class.isAssignableFrom(bodyType) || return (bodyType != null && (ResponseBodyEmitter.class.isAssignableFrom(bodyType) ||
this.reactiveHandler.isReactiveType(bodyType)); this.reactiveHandler.isReactiveType(bodyType)));
} }
@Override @Override
@SuppressWarnings("resource")
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -259,7 +259,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
this.returnValue = returnValue; this.returnValue = returnValue;
this.returnType = (returnValue instanceof ReactiveTypeHandler.CollectedValuesList ? this.returnType = (returnValue instanceof ReactiveTypeHandler.CollectedValuesList ?
((ReactiveTypeHandler.CollectedValuesList) returnValue).getReturnType() : ((ReactiveTypeHandler.CollectedValuesList) returnValue).getReturnType() :
ResolvableType.forType(super.getGenericParameterType()).getGeneric(0)); ResolvableType.forType(super.getGenericParameterType()).getGeneric());
} }
public ConcurrentResultMethodParameter(ConcurrentResultMethodParameter original) { public ConcurrentResultMethodParameter(ConcurrentResultMethodParameter original) {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -50,13 +50,14 @@ public class StreamingResponseBodyReturnValueHandler implements HandlerMethodRet
return true; return true;
} }
else if (ResponseEntity.class.isAssignableFrom(returnType.getParameterType())) { else if (ResponseEntity.class.isAssignableFrom(returnType.getParameterType())) {
Class<?> bodyType = ResolvableType.forMethodParameter(returnType).getGeneric(0).resolve(); Class<?> bodyType = ResolvableType.forMethodParameter(returnType).getGeneric().resolve();
return (bodyType != null && StreamingResponseBody.class.isAssignableFrom(bodyType)); return (bodyType != null && StreamingResponseBody.class.isAssignableFrom(bodyType));
} }
return false; return false;
} }
@Override @Override
@SuppressWarnings("resource")
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {