@Nullable all the way: null-safety at field level

This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.

Issue: SPR-15720
This commit is contained in:
Juergen Hoeller
2017-06-30 01:53:45 +02:00
parent c4694c3f5c
commit cc74a2891a
936 changed files with 6090 additions and 2806 deletions

View File

@@ -40,28 +40,38 @@ import static java.time.format.DateTimeFormatter.*;
*/
public class ContentDisposition {
@Nullable
private final String type;
@Nullable
private final String name;
@Nullable
private final String filename;
@Nullable
private final Charset charset;
@Nullable
private final Long size;
@Nullable
private final ZonedDateTime creationDate;
@Nullable
private final ZonedDateTime modificationDate;
@Nullable
private final ZonedDateTime readDate;
/**
* Private constructor. See static factory methods in this class.
*/
private ContentDisposition(@Nullable String type, @Nullable String name, @Nullable String filename, @Nullable Charset charset, @Nullable Long size,
@Nullable ZonedDateTime creationDate, @Nullable ZonedDateTime modificationDate, @Nullable ZonedDateTime readDate) {
private ContentDisposition(@Nullable String type, @Nullable String name, @Nullable String filename,
@Nullable Charset charset, @Nullable Long size, @Nullable ZonedDateTime creationDate,
@Nullable ZonedDateTime modificationDate, @Nullable ZonedDateTime readDate) {
this.type = type;
this.name = name;
this.filename = filename;
@@ -435,28 +445,34 @@ public class ContentDisposition {
* Build the content disposition
*/
ContentDisposition build();
}
private static class BuilderImpl implements Builder {
private String type;
@Nullable
private String name;
@Nullable
private String filename;
@Nullable
private Charset charset;
@Nullable
private Long size;
@Nullable
private ZonedDateTime creationDate;
@Nullable
private ZonedDateTime modificationDate;
@Nullable
private ZonedDateTime readDate;
public BuilderImpl(String type) {
Assert.hasText(type, "'type' must not be not empty");
this.type = type;

View File

@@ -64,6 +64,7 @@ public class HttpEntity<T> {
private final HttpHeaders headers;
@Nullable
private final T body;
@@ -151,13 +152,9 @@ public class HttpEntity<T> {
StringBuilder builder = new StringBuilder("<");
if (this.body != null) {
builder.append(this.body);
if (this.headers != null) {
builder.append(',');
}
}
if (this.headers != null) {
builder.append(this.headers);
builder.append(',');
}
builder.append(this.headers);
builder.append('>');
return builder.toString();
}

View File

@@ -212,6 +212,7 @@ public abstract class HttpRange {
private final long firstPos;
@Nullable
private final Long lastPos;
public ByteRange(long firstPos, @Nullable Long lastPos) {

View File

@@ -62,10 +62,12 @@ import org.springframework.util.ObjectUtils;
*/
public class RequestEntity<T> extends HttpEntity<T> {
@Nullable
private final HttpMethod method;
private final URI url;
@Nullable
private final Type type;

View File

@@ -49,7 +49,7 @@ abstract class AbstractBufferingAsyncClientHttpRequest extends AbstractAsyncClie
headers.setContentLength(bytes.length);
}
ListenableFuture<ClientHttpResponse> result = executeInternal(headers, bytes);
this.bufferedOutput = null;
this.bufferedOutput = new ByteArrayOutputStream(0);
return result;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -46,7 +46,7 @@ abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequ
headers.setContentLength(bytes.length);
}
ClientHttpResponse result = executeInternal(headers, bytes);
this.bufferedOutput = null;
this.bufferedOutput = new ByteArrayOutputStream(0);
return result;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -22,6 +22,7 @@ import java.io.InputStream;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
/**
@@ -35,6 +36,7 @@ final class BufferingClientHttpResponseWrapper implements ClientHttpResponse {
private final ClientHttpResponse response;
@Nullable
private byte[] body;

View File

@@ -33,6 +33,7 @@ import org.apache.http.protocol.HttpContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -50,6 +51,7 @@ import org.springframework.util.Assert;
public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory
implements AsyncClientHttpRequestFactory, InitializingBean {
@Nullable
private HttpAsyncClient asyncClient;
@@ -126,6 +128,7 @@ public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsC
* @since 4.3.10
* @see #getHttpClient()
*/
@Nullable
public HttpAsyncClient getAsyncClient() {
return this.asyncClient;
}
@@ -158,19 +161,21 @@ public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsC
startAsyncClient();
}
private void startAsyncClient() {
HttpAsyncClient asyncClient = getAsyncClient();
if (asyncClient instanceof CloseableHttpAsyncClient) {
CloseableHttpAsyncClient closeableAsyncClient = (CloseableHttpAsyncClient) asyncClient;
private HttpAsyncClient startAsyncClient() {
HttpAsyncClient client = getAsyncClient();
Assert.state(client != null, "No HttpAsyncClient set");
if (client instanceof CloseableHttpAsyncClient) {
CloseableHttpAsyncClient closeableAsyncClient = (CloseableHttpAsyncClient) client;
if (!closeableAsyncClient.isRunning()) {
closeableAsyncClient.start();
}
}
return client;
}
@Override
public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException {
startAsyncClient();
HttpAsyncClient client = startAsyncClient();
HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri);
postProcessHttpRequest(httpRequest);
@@ -187,14 +192,14 @@ public class HttpComponentsAsyncClientHttpRequestFactory extends HttpComponentsC
config = ((Configurable) httpRequest).getConfig();
}
if (config == null) {
config = createRequestConfig(getAsyncClient());
config = createRequestConfig(client);
}
if (config != null) {
context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);
}
}
return new HttpComponentsAsyncClientHttpRequest(getAsyncClient(), httpRequest, context);
return new HttpComponentsAsyncClientHttpRequest(client, httpRequest, context);
}
@Override

View File

@@ -24,6 +24,7 @@ import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
/**
@@ -43,6 +44,7 @@ final class HttpComponentsAsyncClientHttpResponse extends AbstractClientHttpResp
private final HttpResponse httpResponse;
@Nullable
private HttpHeaders headers;

View File

@@ -59,8 +59,10 @@ import org.springframework.util.Assert;
*/
public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean {
@Nullable
private HttpClient httpClient;
@Nullable
private RequestConfig requestConfig;
private boolean bufferRequestBody = true;
@@ -97,6 +99,7 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
* Return the {@code HttpClient} used for
* {@linkplain #createRequest(URI, HttpMethod) synchronous execution}.
*/
@Nullable
public HttpClient getHttpClient() {
return this.httpClient;
}
@@ -152,6 +155,9 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
HttpClient client = getHttpClient();
Assert.state(client != null, "No HttpClient set");
HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri);
postProcessHttpRequest(httpRequest);
HttpContext context = createHttpContext(httpMethod, uri);
@@ -167,7 +173,7 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
config = ((Configurable) httpRequest).getConfig();
}
if (config == null) {
config = createRequestConfig(getHttpClient());
config = createRequestConfig(client);
}
if (config != null) {
context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);
@@ -175,10 +181,10 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
}
if (this.bufferRequestBody) {
return new HttpComponentsClientHttpRequest(getHttpClient(), httpRequest, context);
return new HttpComponentsClientHttpRequest(client, httpRequest, context);
}
else {
return new HttpComponentsStreamingClientHttpRequest(getHttpClient(), httpRequest, context);
return new HttpComponentsStreamingClientHttpRequest(client, httpRequest, context);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -26,6 +26,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
/**
@@ -43,6 +44,7 @@ final class HttpComponentsClientHttpResponse extends AbstractClientHttpResponse
private final HttpResponse httpResponse;
@Nullable
private HttpHeaders headers;

View File

@@ -54,6 +54,7 @@ final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpR
private final HttpContext httpContext;
@Nullable
private Body body;
@@ -89,9 +90,9 @@ final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpR
protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException {
HttpComponentsClientHttpRequest.addHeaders(this.httpRequest, headers);
if (this.httpRequest instanceof HttpEntityEnclosingRequest && body != null) {
if (this.httpRequest instanceof HttpEntityEnclosingRequest && this.body != null) {
HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) this.httpRequest;
HttpEntity requestEntity = new StreamingHttpEntity(getHeaders(), body);
HttpEntity requestEntity = new StreamingHttpEntity(getHeaders(), this.body);
entityEnclosingRequest.setEntity(requestEntity);
}

View File

@@ -39,6 +39,7 @@ import io.netty.handler.timeout.ReadTimeoutHandler;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -75,12 +76,14 @@ public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory,
private int maxResponseSize = DEFAULT_MAX_RESPONSE_SIZE;
@Nullable
private SslContext sslContext;
private int connectTimeout = -1;
private int readTimeout = -1;
@Nullable
private volatile Bootstrap bootstrap;
@@ -183,10 +186,12 @@ public class Netty4ClientHttpRequestFactory implements ClientHttpRequestFactory,
return buildBootstrap(uri, true);
}
else {
if (this.bootstrap == null) {
this.bootstrap = buildBootstrap(uri, false);
Bootstrap bootstrap = this.bootstrap;
if (bootstrap == null) {
bootstrap = buildBootstrap(uri, false);
this.bootstrap = bootstrap;
}
return this.bootstrap;
return bootstrap;
}
}

View File

@@ -25,6 +25,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -43,6 +44,7 @@ class Netty4ClientHttpResponse extends AbstractClientHttpResponse {
private final ByteBufInputStream body;
@Nullable
private volatile HttpHeaders headers;
@@ -70,14 +72,15 @@ class Netty4ClientHttpResponse extends AbstractClientHttpResponse {
@Override
public HttpHeaders getHeaders() {
if (this.headers == null) {
HttpHeaders headers = new HttpHeaders();
HttpHeaders headers = this.headers;
if (headers == null) {
headers = new HttpHeaders();
for (Map.Entry<String, String> entry : this.nettyResponse.headers()) {
headers.add(entry.getKey(), entry.getValue());
}
this.headers = headers;
}
return this.headers;
return headers;
}
@Override

View File

@@ -23,6 +23,7 @@ import okhttp3.Response;
import okhttp3.ResponseBody;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
@@ -38,7 +39,8 @@ class OkHttp3ClientHttpResponse extends AbstractClientHttpResponse {
private final Response response;
private HttpHeaders headers;
@Nullable
private volatile HttpHeaders headers;
public OkHttp3ClientHttpResponse(Response response) {
@@ -65,8 +67,9 @@ class OkHttp3ClientHttpResponse extends AbstractClientHttpResponse {
@Override
public HttpHeaders getHeaders() {
if (this.headers == null) {
HttpHeaders headers = new HttpHeaders();
HttpHeaders headers = this.headers;
if (headers == null) {
headers = new HttpHeaders();
for (String headerName : this.response.headers().names()) {
for (String headerValue : this.response.headers(headerName)) {
headers.add(headerName, headerValue);
@@ -74,7 +77,7 @@ class OkHttp3ClientHttpResponse extends AbstractClientHttpResponse {
}
this.headers = headers;
}
return this.headers;
return headers;
}
@Override

View File

@@ -43,6 +43,7 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
private static final int DEFAULT_CHUNK_SIZE = 4096;
@Nullable
private Proxy proxy;
private boolean bufferRequestBody = true;
@@ -55,6 +56,7 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
private boolean outputStreaming = true;
@Nullable
private AsyncListenableTaskExecutor taskExecutor;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -21,6 +21,7 @@ import java.io.InputStream;
import java.net.HttpURLConnection;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
@@ -37,8 +38,10 @@ final class SimpleClientHttpResponse extends AbstractClientHttpResponse {
private final HttpURLConnection connection;
@Nullable
private HttpHeaders headers;
@Nullable
private InputStream responseStream;

View File

@@ -25,6 +25,7 @@ import java.util.concurrent.Callable;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
import org.springframework.util.concurrent.ListenableFuture;
@@ -45,6 +46,7 @@ final class SimpleStreamingAsyncClientHttpRequest extends AbstractAsyncClientHtt
private final int chunkSize;
@Nullable
private OutputStream body;
private final boolean outputStreaming;

View File

@@ -24,6 +24,7 @@ import java.net.URISyntaxException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
/**
@@ -40,6 +41,7 @@ final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest {
private final int chunkSize;
@Nullable
private OutputStream body;
private final boolean outputStreaming;

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.codec;
import java.util.ArrayList;
@@ -35,10 +36,10 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Default implementation of {@link CodecConfigurer}.
*
@@ -63,7 +64,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
protected AbstractCodecConfigurer(AbstractDefaultCodecs defaultCodecs) {
Assert.notNull(defaultCodecs, "'defaultCodecs' is required.");
Assert.notNull(defaultCodecs, "'defaultCodecs' is required");
this.defaultCodecs = defaultCodecs;
this.defaultCodecs.setCustomCodecs(this.customCodecs);
}
@@ -117,13 +118,15 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
private boolean registerDefaults = true;
@Nullable
private Jackson2JsonDecoder jackson2Decoder;
@Nullable
private Jackson2JsonEncoder jackson2Encoder;
@Nullable
private DefaultCustomCodecs customCodecs;
public void setRegisterDefaults(boolean registerDefaults) {
this.registerDefaults = registerDefaults;
}
@@ -139,6 +142,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
this.customCodecs = customCodecs;
}
@Nullable
public DefaultCustomCodecs getCustomCodecs() {
return this.customCodecs;
}
@@ -149,7 +153,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
}
protected Jackson2JsonDecoder jackson2Decoder() {
return this.jackson2Decoder != null ? this.jackson2Decoder : new Jackson2JsonDecoder();
return (this.jackson2Decoder != null ? this.jackson2Decoder : new Jackson2JsonDecoder());
}
@Override
@@ -158,7 +162,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
}
protected Jackson2JsonEncoder jackson2Encoder() {
return this.jackson2Encoder != null ? this.jackson2Encoder : new Jackson2JsonEncoder();
return (this.jackson2Encoder != null ? this.jackson2Encoder : new Jackson2JsonEncoder());
}
// Readers...
@@ -244,11 +248,12 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
protected static class DefaultCustomCodecs implements CustomCodecs {
private final List<HttpMessageReader<?>> typedReaders = new ArrayList<>();
private final List<HttpMessageWriter<?>> typedWriters = new ArrayList<>();
private final List<HttpMessageReader<?>> objectReaders = new ArrayList<>();
private final List<HttpMessageWriter<?>> objectWriters = new ArrayList<>();
private final List<HttpMessageWriter<?>> objectWriters = new ArrayList<>();
@Override
public void decoder(Decoder<?> decoder) {
@@ -272,7 +277,6 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
(canWriteObject ? this.objectWriters : this.typedWriters).add(writer);
}
public List<HttpMessageReader<?>> getTypedReaders() {
return this.typedReaders;
}

View File

@@ -23,6 +23,7 @@ import java.util.List;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.Encoder;
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
import org.springframework.lang.Nullable;
/**
* Default implementation of {@link ClientCodecConfigurer}.
@@ -32,26 +33,24 @@ import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
*/
class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements ClientCodecConfigurer {
public DefaultClientCodecConfigurer() {
super(new ClientDefaultCodecsImpl());
}
@Override
public ClientDefaultCodecs defaultCodecs() {
return (ClientDefaultCodecs) super.defaultCodecs();
}
private static class ClientDefaultCodecsImpl extends AbstractDefaultCodecs
implements ClientDefaultCodecs {
private static class ClientDefaultCodecsImpl extends AbstractDefaultCodecs implements ClientDefaultCodecs {
@Nullable
private DefaultMultipartCodecs multipartCodecs;
@Nullable
private Decoder<?> sseDecoder;
@Override
public MultipartCodecs multipartCodecs() {
if (this.multipartCodecs == null) {
@@ -65,7 +64,6 @@ class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements Cl
this.sseDecoder = decoder;
}
@Override
protected boolean splitTextOnNewLine() {
return false;
@@ -105,22 +103,27 @@ class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements Cl
partWriters = this.multipartCodecs.getWriters();
}
else {
DefaultCustomCodecs customCodecs = getCustomCodecs();
partWriters = new ArrayList<>();
partWriters.addAll(super.getTypedWriters());
partWriters.addAll(getCustomCodecs().getTypedWriters());
if (customCodecs != null) {
partWriters.addAll(customCodecs.getTypedWriters());
}
partWriters.addAll(super.getObjectWriters());
partWriters.addAll(getCustomCodecs().getObjectWriters());
if (customCodecs != null) {
partWriters.addAll(customCodecs.getObjectWriters());
}
partWriters.addAll(super.getCatchAllWriters());
}
return new MultipartHttpMessageWriter(partWriters);
}
}
private static class DefaultMultipartCodecs implements MultipartCodecs {
private final List<HttpMessageWriter<?>> writers = new ArrayList<>();
@Override
public MultipartCodecs encoder(Encoder<?> encoder) {
writer(new EncoderHttpMessageWriter<>(encoder));

View File

@@ -22,6 +22,7 @@ import java.util.List;
import org.springframework.core.codec.Encoder;
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -32,16 +33,15 @@ import org.springframework.util.ClassUtils;
*/
class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements ServerCodecConfigurer {
static final boolean synchronossMultipartPresent =
ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser",
AbstractCodecConfigurer.class.getClassLoader());
static final boolean synchronossMultipartPresent = ClassUtils.isPresent(
"org.synchronoss.cloud.nio.multipart.NioMultipartParser",
DefaultServerCodecConfigurer.class.getClassLoader());
public DefaultServerCodecConfigurer() {
super(new ServerDefaultCodecsImpl());
}
@Override
public ServerDefaultCodecs defaultCodecs() {
return (ServerDefaultCodecs) super.defaultCodecs();
@@ -51,18 +51,16 @@ class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements Se
/**
* Default implementation of {@link ServerDefaultCodecs}.
*/
private static class ServerDefaultCodecsImpl extends AbstractDefaultCodecs
implements ServerDefaultCodecs {
private static class ServerDefaultCodecsImpl extends AbstractDefaultCodecs implements ServerDefaultCodecs {
@Nullable
private Encoder<?> sseEncoder;
@Override
public void serverSentEventEncoder(Encoder<?> encoder) {
this.sseEncoder = encoder;
}
@Override
protected boolean splitTextOnNewLine() {
return true;

View File

@@ -35,7 +35,6 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* {@code HttpMessageWriter} that wraps and delegates to a {@link Encoder}.
*
@@ -54,6 +53,7 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
private final List<MediaType> mediaTypes;
@Nullable
private final MediaType defaultMediaType;

View File

@@ -34,7 +34,6 @@ import org.springframework.core.codec.Encoder;
*/
public interface ServerCodecConfigurer extends CodecConfigurer {
@Override
ServerDefaultCodecs defaultCodecs();

View File

@@ -36,18 +36,25 @@ import org.springframework.lang.Nullable;
*/
public class ServerSentEvent<T> {
@Nullable
private final String id;
@Nullable
private final String event;
@Nullable
private final Duration retry;
@Nullable
private final String comment;
@Nullable
private final T data;
private ServerSentEvent(String id, String event, Duration retry, String comment, T data) {
private ServerSentEvent(@Nullable String id, @Nullable String event, @Nullable Duration retry,
@Nullable String comment, @Nullable T data) {
this.id = id;
this.event = event;
this.retry = retry;
@@ -167,7 +174,7 @@ public class ServerSentEvent<T> {
* @param data the value of the data field
* @return {@code this} builder
*/
Builder<T> data(T data);
Builder<T> data(@Nullable T data);
/**
* Builds the event.
@@ -179,14 +186,19 @@ public class ServerSentEvent<T> {
private static class BuilderImpl<T> implements Builder<T> {
@Nullable
private String id;
@Nullable
private String event;
@Nullable
private Duration retry;
@Nullable
private String comment;
@Nullable
private T data;
public BuilderImpl() {
@@ -221,7 +233,7 @@ public class ServerSentEvent<T> {
}
@Override
public Builder<T> data(T data) {
public Builder<T> data(@Nullable T data) {
this.data = data;
return this;
}

View File

@@ -29,6 +29,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.CodecException;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.StringDecoder;
import org.springframework.core.io.buffer.DataBuffer;
@@ -39,12 +40,11 @@ import org.springframework.http.MediaType;
import org.springframework.http.ReactiveHttpInputMessage;
import org.springframework.lang.Nullable;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.*;
/**
* Reader that supports a stream of {@link ServerSentEvent}s and also plain
* {@link Object}s which is the same as an {@link ServerSentEvent} with data
* only.
* {@link Object}s which is the same as an {@link ServerSentEvent} with data only.
*
* @author Sebastien Deleuze
* @author Rossen Stoyanchev
@@ -59,6 +59,7 @@ public class ServerSentEventHttpMessageReader implements HttpMessageReader<Objec
private static final StringDecoder stringDecoder = StringDecoder.textPlainOnly(false);
@Nullable
private final Decoder<?> decoder;
@@ -178,11 +179,16 @@ public class ServerSentEventHttpMessageReader implements HttpMessageReader<Objec
return sseBuilder.build();
}
@Nullable
private Object decodeData(String data, ResolvableType dataType, Map<String, Object> hints) {
if (String.class == dataType.resolve()) {
return data.substring(0, data.length() - 1);
}
if (this.decoder == null) {
return Flux.error(new CodecException("No SSE decoder configured and the data is not String."));
}
byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
Mono<DataBuffer> input = Mono.just(bufferFactory.wrap(bytes));

View File

@@ -48,10 +48,9 @@ import org.springframework.lang.Nullable;
*/
public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Object> {
private static final List<MediaType> WRITABLE_MEDIA_TYPES =
Collections.singletonList(MediaType.TEXT_EVENT_STREAM);
private static final List<MediaType> WRITABLE_MEDIA_TYPES = Collections.singletonList(MediaType.TEXT_EVENT_STREAM);
@Nullable
private final Encoder<?> encoder;

View File

@@ -230,6 +230,7 @@ public class MultipartHttpMessageWriter implements HttpMessageWriter<MultiValueM
private final AtomicBoolean committed = new AtomicBoolean();
@Nullable
private Flux<DataBuffer> body;
public MultipartHttpOutputMessage(DataBufferFactory bufferFactory, Charset charset) {

View File

@@ -70,8 +70,10 @@ public class BufferedImageHttpMessageConverter implements HttpMessageConverter<B
private final List<MediaType> readableMediaTypes = new ArrayList<>();
@Nullable
private MediaType defaultContentType;
@Nullable
private File cacheDir;
@@ -112,6 +114,7 @@ public class BufferedImageHttpMessageConverter implements HttpMessageConverter<B
* Returns the default {@code Content-Type} to be used for writing.
* Called when {@link #write} is invoked without a specified content type parameter.
*/
@Nullable
public MediaType getDefaultContentType() {
return this.defaultContentType;
}

View File

@@ -100,6 +100,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
private Charset charset = DEFAULT_CHARSET;
@Nullable
private Charset multipartCharset;
@@ -365,7 +366,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
* we encode directly using the configured {@link #setCharset(Charset)}.
*/
private boolean isFilenameCharsetSet() {
return this.multipartCharset != null;
return (this.multipartCharset != null);
}
private void writeParts(OutputStream os, MultiValueMap<String, Object> parts, byte[] boundary) throws IOException {

View File

@@ -45,6 +45,7 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
@Nullable
private volatile List<Charset> availableCharsets;
private boolean writeAcceptCharset = true;
@@ -110,11 +111,12 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
* @return the list of accepted charsets
*/
protected List<Charset> getAcceptedCharsets() {
if (this.availableCharsets == null) {
this.availableCharsets = new ArrayList<>(
Charset.availableCharsets().values());
List<Charset> charsets = this.availableCharsets;
if (charsets == null) {
charsets = new ArrayList<>(Charset.availableCharsets().values());
this.availableCharsets = charsets;
}
return this.availableCharsets;
return charsets;
}
private Charset getContentTypeCharset(@Nullable MediaType contentType) {

View File

@@ -71,8 +71,10 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
protected ObjectMapper objectMapper;
@Nullable
private Boolean prettyPrint;
@Nullable
private PrettyPrinter ssePrettyPrinter;
@@ -119,6 +121,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
/**
* Return the underlying {@code ObjectMapper} for this view.
*/
@Nullable
public ObjectMapper getObjectMapper() {
return this.objectMapper;
}

View File

@@ -52,6 +52,7 @@ public abstract class AbstractJsonHttpMessageConverter extends AbstractGenericHt
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
@Nullable
private String jsonPrefix;

View File

@@ -23,6 +23,7 @@ import com.google.gson.GsonBuilder;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
/**
* A {@link FactoryBean} for creating a Google Gson 2.x {@link Gson} instance.
@@ -41,8 +42,10 @@ public class GsonFactoryBean implements FactoryBean<Gson>, InitializingBean {
private boolean disableHtmlEscaping = false;
@Nullable
private String dateFormatPattern;
@Nullable
private Gson gson;

View File

@@ -59,6 +59,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;
import org.springframework.context.ApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StreamUtils;
@@ -107,26 +108,37 @@ public class Jackson2ObjectMapperBuilder {
private boolean createXmlMapper = false;
@Nullable
private JsonFactory factory;
@Nullable
private DateFormat dateFormat;
@Nullable
private Locale locale;
@Nullable
private TimeZone timeZone;
@Nullable
private AnnotationIntrospector annotationIntrospector;
@Nullable
private PropertyNamingStrategy propertyNamingStrategy;
@Nullable
private TypeResolverBuilder<?> defaultTyping;
@Nullable
private JsonInclude.Include serializationInclusion;
@Nullable
private FilterProvider filters;
@Nullable
private List<Module> modules;
@Nullable
private Class<? extends Module>[] moduleClasses;
private boolean findModulesViaServiceLoader = false;
@@ -135,10 +147,13 @@ public class Jackson2ObjectMapperBuilder {
private ClassLoader moduleClassLoader = getClass().getClassLoader();
@Nullable
private HandlerInstantiator handlerInstantiator;
@Nullable
private ApplicationContext applicationContext;
@Nullable
private Boolean defaultUseWrapper;

View File

@@ -46,6 +46,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;
/**
* A {@link FactoryBean} for creating a Jackson 2.x {@link ObjectMapper} (default) or
@@ -144,6 +145,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper
private final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
@Nullable
private ObjectMapper objectMapper;

View File

@@ -22,6 +22,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
/**
* Implementation of {@link org.springframework.http.converter.HttpMessageConverter} that can read and
@@ -46,6 +47,7 @@ import org.springframework.http.MediaType;
*/
public class MappingJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
@Nullable
private String jsonPrefix;

View File

@@ -36,15 +36,16 @@ public class MappingJacksonInputMessage implements HttpInputMessage {
private final HttpHeaders headers;
@Nullable
private Class<?> deserializationView;
public MappingJacksonInputMessage(@Nullable InputStream body, HttpHeaders headers) {
public MappingJacksonInputMessage(InputStream body, HttpHeaders headers) {
this.body = body;
this.headers = headers;
}
public MappingJacksonInputMessage(@Nullable InputStream body, HttpHeaders headers, Class<?> deserializationView) {
public MappingJacksonInputMessage(InputStream body, HttpHeaders headers, Class<?> deserializationView) {
this(body, headers);
this.deserializationView = deserializationView;
}

View File

@@ -74,7 +74,7 @@ public class MappingJacksonValue {
* @see com.fasterxml.jackson.databind.ObjectMapper#writerWithView(Class)
* @see com.fasterxml.jackson.annotation.JsonView
*/
public void setSerializationView(@Nullable Class<?> serializationView) {
public void setSerializationView(Class<?> serializationView) {
this.serializationView = serializationView;
}

View File

@@ -91,6 +91,7 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
private final ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
@Nullable
private final ProtobufFormatSupport protobufFormatSupport;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -48,8 +48,10 @@ import org.springframework.util.Assert;
*/
public class MarshallingHttpMessageConverter extends AbstractXmlHttpMessageConverter<Object> {
@Nullable
private Marshaller marshaller;
@Nullable
private Unmarshaller unmarshaller;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 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.
@@ -24,6 +24,7 @@ import javax.servlet.AsyncListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -41,6 +42,7 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ
private final ServletServerHttpResponse response;
@Nullable
private AsyncContext asyncContext;
private AtomicBoolean asyncCompleted = new AtomicBoolean(false);
@@ -101,7 +103,7 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ
@Override
public void complete() {
if (isStarted() && !isCompleted()) {
if (this.asyncContext != null && isStarted() && !isCompleted()) {
this.asyncContext.complete();
}
}

View File

@@ -40,6 +40,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.InvalidMediaTypeException;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.StringUtils;
@@ -60,8 +61,10 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
private final HttpServletRequest servletRequest;
@Nullable
private HttpHeaders headers;
@Nullable
private ServerHttpAsyncRequestControl asyncRequestControl;

View File

@@ -56,6 +56,7 @@ public abstract class AbstractListenerReadPublisher<T> implements Publisher<T> {
private static final AtomicLongFieldUpdater<AbstractListenerReadPublisher> DEMAND_FIELD_UPDATER =
AtomicLongFieldUpdater.newUpdater(AbstractListenerReadPublisher.class, "demand");
@Nullable
private Subscriber<? super T> subscriber;
@@ -126,6 +127,7 @@ public abstract class AbstractListenerReadPublisher<T> implements Publisher<T> {
if (r != Long.MAX_VALUE) {
DEMAND_FIELD_UPDATER.addAndGet(this, -1L);
}
Assert.state(this.subscriber != null, "No subscriber");
this.subscriber.onNext(data);
}
else {
@@ -144,7 +146,6 @@ public abstract class AbstractListenerReadPublisher<T> implements Publisher<T> {
private final AbstractListenerReadPublisher<?> publisher;
public ReadSubscription(AbstractListenerReadPublisher<?> publisher) {
this.publisher = publisher;
}

View File

@@ -26,6 +26,7 @@ import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -48,6 +49,7 @@ public abstract class AbstractListenerWriteFlushProcessor<T> implements Processo
private volatile boolean subscriberCompleted;
@Nullable
private Subscription subscription;
@@ -105,8 +107,8 @@ public abstract class AbstractListenerWriteFlushProcessor<T> implements Processo
/**
* Invoked when an error happens while flushing. Defaults to no-op.
* Servlet 3.1 based implementations will receive
* {@link AsyncListener#onError(Throwable)} event.
* Servlet 3.1 based implementations will receive an
* {@link javax.servlet.AsyncListener#onError} event.
*/
protected void flushingFailed(Throwable t) {
}
@@ -185,6 +187,7 @@ public abstract class AbstractListenerWriteFlushProcessor<T> implements Processo
}
else {
if (processor.changeState(this, REQUESTED)) {
Assert.state(processor.subscription != null, "No subscription");
processor.subscription.request(1);
}
}

View File

@@ -25,6 +25,7 @@ import org.reactivestreams.Processor;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -48,10 +49,12 @@ public abstract class AbstractListenerWriteProcessor<T> implements Processor<T,
private final AtomicReference<State> state = new AtomicReference<>(State.UNSUBSCRIBED);
@Nullable
protected volatile T currentData;
private volatile boolean subscriberCompleted;
@Nullable
private Subscription subscription;
@@ -145,8 +148,8 @@ public abstract class AbstractListenerWriteProcessor<T> implements Processor<T,
/**
* Writes the given data to the output.
* @param data the data to write
* @return whether the data was fully written (true)and new data can be
* requested or otherwise (false)
* @return whether the data was fully written ({@code true})
* and new data can be requested, or otherwise ({@code false})
*/
protected abstract boolean write(T data) throws IOException;
@@ -232,6 +235,7 @@ public abstract class AbstractListenerWriteProcessor<T> implements Processor<T,
@Override
public <T> void onNext(AbstractListenerWriteProcessor<T> processor, T data) {
if (processor.isDataEmpty(data)) {
Assert.state(processor.subscription != null, "No subscription");
processor.subscription.request(1);
}
else {
@@ -264,6 +268,7 @@ public abstract class AbstractListenerWriteProcessor<T> implements Processor<T,
public <T> void onWritePossible(AbstractListenerWriteProcessor<T> processor) {
if (processor.changeState(this, WRITING)) {
T data = processor.currentData;
Assert.state(data != null, "No data");
try {
boolean writeCompleted = processor.write(data);
if (writeCompleted) {
@@ -271,6 +276,7 @@ public abstract class AbstractListenerWriteProcessor<T> implements Processor<T,
if (!processor.subscriberCompleted) {
processor.changeState(WRITING, REQUESTED);
processor.suspendWriting();
Assert.state(processor.subscription != null, "No subscription");
processor.subscription.request(1);
}
else {

View File

@@ -23,6 +23,7 @@ import java.util.regex.Pattern;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -45,8 +46,10 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
private final HttpHeaders headers;
@Nullable
private MultiValueMap<String, String> queryParams;
@Nullable
private MultiValueMap<String, HttpCookie> cookies;

View File

@@ -62,12 +62,14 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
private final DataBufferFactory dataBufferFactory;
@Nullable
private HttpStatus statusCode;
private final HttpHeaders headers;
private final MultiValueMap<String, ResponseCookie> cookies;
@Nullable
private Function<String, String> urlEncoder = url -> url;
private final AtomicReference<State> state = new AtomicReference<>(State.NEW);
@@ -105,6 +107,7 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
}
@Override
@Nullable
public HttpStatus getStatusCode() {
return this.statusCode;
}

View File

@@ -45,7 +45,8 @@ import org.springframework.util.Assert;
public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
private final Function<Publisher<T>, Publisher<Void>> writeFunction;
private final Flux<T> source;
private final Flux<T> source;
public ChannelSendOperator(Publisher<? extends T> source, Function<Publisher<T>, Publisher<Void>> writeFunction) {
@@ -53,16 +54,20 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
this.writeFunction = writeFunction;
}
@Override
@Nullable
@SuppressWarnings("rawtypes")
public Object scanUnsafe(Attr key) {
if (key == IntAttr.PREFETCH) return Integer.MAX_VALUE;
if (key == ScannableAttr.PARENT) return source;
if (key == IntAttr.PREFETCH) {
return Integer.MAX_VALUE;
}
if (key == ScannableAttr.PARENT) {
return this.source;
}
return null;
}
@Override
public void subscribe(Subscriber<? super Void> s, Context ctx) {
this.source.subscribe(new WriteWithBarrier(s), ctx);
@@ -83,15 +88,18 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
private boolean beforeFirstEmission = true;
/** Cached signal before readyToWrite */
@Nullable
private T item;
/** Cached 1st/2nd signal before readyToWrite */
@Nullable
private Throwable error;
/** Cached 1st/2nd signal before readyToWrite */
private boolean completed = false;
/** The actual writeSubscriber vs the downstream completion subscriber */
@Nullable
private Subscriber<? super T> writeSubscriber;
public WriteWithBarrier(Subscriber<? super Void> subscriber) {
@@ -107,12 +115,12 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
@Override
public void doNext(T item) {
if (this.readyToWrite) {
this.writeSubscriber.onNext(item);
obtainWriteSubscriber().onNext(item);
return;
}
synchronized (this) {
if (this.readyToWrite) {
this.writeSubscriber.onNext(item);
obtainWriteSubscriber().onNext(item);
}
else if (this.beforeFirstEmission) {
this.item = item;
@@ -120,7 +128,9 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
writeFunction.apply(this).subscribe(new DownstreamBridge(downstream()));
}
else {
subscription.cancel();
if (this.subscription != null) {
this.subscription.cancel();
}
downstream().onError(new IllegalStateException("Unexpected item."));
}
}
@@ -129,12 +139,12 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
@Override
public void doError(Throwable ex) {
if (this.readyToWrite) {
this.writeSubscriber.onError(ex);
obtainWriteSubscriber().onError(ex);
return;
}
synchronized (this) {
if (this.readyToWrite) {
this.writeSubscriber.onError(ex);
obtainWriteSubscriber().onError(ex);
}
else if (this.beforeFirstEmission) {
this.beforeFirstEmission = false;
@@ -149,12 +159,12 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
@Override
public void doComplete() {
if (this.readyToWrite) {
this.writeSubscriber.onComplete();
obtainWriteSubscriber().onComplete();
return;
}
synchronized (this) {
if (this.readyToWrite) {
this.writeSubscriber.onComplete();
obtainWriteSubscriber().onComplete();
}
else if (this.beforeFirstEmission) {
this.completed = true;
@@ -170,9 +180,8 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
@Override
public void subscribe(Subscriber<? super T> writeSubscriber) {
synchronized (this) {
Assert.isNull(this.writeSubscriber, "Only one writeSubscriber supported");
Assert.state(this.writeSubscriber == null, "Only one write subscriber supported");
this.writeSubscriber = writeSubscriber;
if (this.error != null || this.completed) {
this.writeSubscriber.onSubscribe(Operators.emptySubscription());
emitCachedSignals();
@@ -189,14 +198,14 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
*/
private boolean emitCachedSignals() {
if (this.item != null) {
this.writeSubscriber.onNext(this.item);
obtainWriteSubscriber().onNext(this.item);
}
if (this.error != null) {
this.writeSubscriber.onError(this.error);
obtainWriteSubscriber().onError(this.error);
return true;
}
if (this.completed) {
this.writeSubscriber.onComplete();
obtainWriteSubscriber().onComplete();
return true;
}
return false;
@@ -222,13 +231,20 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
}
}
}
private Subscriber<? super T> obtainWriteSubscriber() {
Assert.state(this.writeSubscriber != null, "No write subscriber");
return this.writeSubscriber;
}
}
// TODO Remove this copy of Reactor 3.0.x Operators.SubscriberAdapter
private static class SubscriberAdapter<I, O> implements Subscriber<I>, Subscription {
protected final Subscriber<? super O> subscriber;
@Nullable
protected Subscription subscription;
public SubscriberAdapter(Subscriber<? super O> subscriber) {
@@ -236,15 +252,16 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
}
public Subscriber<? super O> downstream() {
return subscriber;
return this.subscriber;
}
@Override
public final void cancel() {
try {
doCancel();
} catch (Throwable throwable) {
doOnSubscriberError(Operators.onOperatorError(subscription, throwable));
}
catch (Throwable throwable) {
doOnSubscriberError(Operators.onOperatorError(this.subscription, throwable));
}
}
@@ -252,7 +269,8 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
public final void onComplete() {
try {
doComplete();
} catch (Throwable throwable) {
}
catch (Throwable throwable) {
doOnSubscriberError(Operators.onOperatorError(throwable));
}
}
@@ -268,15 +286,15 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
doNext(i);
}
catch (Throwable throwable) {
doOnSubscriberError(Operators.onOperatorError(subscription, throwable, i));
doOnSubscriberError(Operators.onOperatorError(this.subscription, throwable, i));
}
}
@Override
public final void onSubscribe(Subscription s) {
if (Operators.validate(subscription, s)) {
if (Operators.validate(this.subscription, s)) {
try {
subscription = s;
this.subscription = s;
doOnSubscribe(s);
}
catch (Throwable throwable) {
@@ -290,7 +308,8 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
try {
Operators.checkRequest(n);
doRequest(n);
} catch (Throwable throwable) {
}
catch (Throwable throwable) {
doCancel();
doOnSubscriberError(Operators.onOperatorError(throwable));
}
@@ -306,28 +325,29 @@ public class ChannelSendOperator<T> extends Mono<Void> implements Scannable {
* @param subscription the subscription to optionally process
*/
protected void doOnSubscribe(Subscription subscription) {
subscriber.onSubscribe(this);
this.subscriber.onSubscribe(this);
}
public Subscription upstream() {
return subscription;
Assert.state(this.subscription != null, "No subscription");
return this.subscription;
}
@SuppressWarnings("unchecked")
protected void doNext(I i) {
subscriber.onNext((O) i);
this.subscriber.onNext((O) i);
}
protected void doError(Throwable throwable) {
subscriber.onError(throwable);
this.subscriber.onError(throwable);
}
protected void doOnSubscriberError(Throwable throwable){
subscriber.onError(throwable);
this.subscriber.onError(throwable);
}
protected void doComplete() {
subscriber.onComplete();
this.subscriber.onComplete();
}
protected void doRequest(long n) {

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.server.reactive;
import java.net.URI;
@@ -38,19 +39,19 @@ class DefaultRequestPath implements RequestPath {
private final PathSegmentContainer pathWithinApplication;
DefaultRequestPath(URI uri, String contextPath, Charset charset) {
DefaultRequestPath(URI uri, @Nullable String contextPath, Charset charset) {
this.fullPath = PathSegmentContainer.parse(uri.getRawPath(), charset);
this.contextPath = initContextPath(this.fullPath, contextPath);
this.pathWithinApplication = extractPathWithinApplication(this.fullPath, this.contextPath);
}
DefaultRequestPath(RequestPath requestPath, String contextPath) {
DefaultRequestPath(RequestPath requestPath, @Nullable String contextPath) {
this.fullPath = requestPath;
this.contextPath = initContextPath(this.fullPath, contextPath);
this.pathWithinApplication = extractPathWithinApplication(this.fullPath, this.contextPath);
}
private static PathSegmentContainer initContextPath(PathSegmentContainer path, String contextPath) {
private static PathSegmentContainer initContextPath(PathSegmentContainer path, @Nullable String contextPath) {
if (!StringUtils.hasText(contextPath) || "/".equals(contextPath)) {
return DefaultPathSegmentContainer.EMPTY_PATH;
}

View File

@@ -36,12 +36,16 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
private final ServerHttpRequest delegate;
@Nullable
private HttpMethod httpMethod;
@Nullable
private String path;
@Nullable
private String contextPath;
@Nullable
private HttpHeaders httpHeaders;
@@ -103,10 +107,10 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
@Nullable
private RequestPath getRequestPathToUse(@Nullable URI uriToUse) {
if (uriToUse == null && this.contextPath == null) {
return null;
}
else if (uriToUse == null) {
if (uriToUse == null) {
if (this.contextPath == null) {
return null;
}
return new DefaultRequestPath(this.delegate.getPath(), this.contextPath);
}
else {
@@ -134,18 +138,21 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
*/
private static class MutativeDecorator extends ServerHttpRequestDecorator {
@Nullable
private final HttpMethod httpMethod;
@Nullable
private final URI uri;
@Nullable
private final RequestPath requestPath;
@Nullable
private final HttpHeaders httpHeaders;
public MutativeDecorator(ServerHttpRequest delegate, HttpMethod method,
@Nullable URI uri, @Nullable RequestPath requestPath,
@Nullable HttpHeaders httpHeaders) {
public MutativeDecorator(ServerHttpRequest delegate, @Nullable HttpMethod method,
@Nullable URI uri, @Nullable RequestPath requestPath, @Nullable HttpHeaders httpHeaders) {
super(delegate);
this.httpMethod = method;

View File

@@ -39,6 +39,7 @@ import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -53,8 +54,10 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons
private final int bufferSize;
@Nullable
private volatile ResponseBodyFlushProcessor bodyFlushProcessor;
@Nullable
private volatile ResponseBodyProcessor bodyProcessor;
private volatile boolean flushOnNext;
@@ -249,8 +252,9 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons
protected Processor<? super DataBuffer, Void> createWriteProcessor() {
try {
ServletOutputStream outputStream = response.getOutputStream();
bodyProcessor = new ResponseBodyProcessor(outputStream);
return bodyProcessor;
ResponseBodyProcessor processor = new ResponseBodyProcessor(outputStream);
bodyProcessor = processor;
return processor;
}
catch (IOException ex) {
throw new UncheckedIOException(ex);

View File

@@ -33,6 +33,7 @@ import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -115,6 +116,7 @@ public class UndertowServerHttpRequest extends AbstractServerHttpRequest {
private final ByteBufferPool byteBufferPool;
@Nullable
private PooledByteBuffer pooledByteBuffer;
public RequestBodyPublisher(HttpServerExchange exchange, DataBufferFactory bufferFactory) {

View File

@@ -40,6 +40,7 @@ import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ZeroCopyHttpOutputMessage;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -55,6 +56,7 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
private final HttpServerExchange exchange;
@Nullable
private StreamSinkChannel responseChannel;
@@ -150,6 +152,7 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
private final StreamSinkChannel channel;
@Nullable
private volatile ByteBuffer byteBuffer;
public ResponseBodyProcessor(StreamSinkChannel channel) {
@@ -171,14 +174,15 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
@Override
protected boolean write(DataBuffer dataBuffer) throws IOException {
if (this.byteBuffer == null) {
ByteBuffer buffer = this.byteBuffer;
if (buffer == null) {
return false;
}
if (logger.isTraceEnabled()) {
logger.trace("write: " + dataBuffer);
}
int total = this.byteBuffer.remaining();
int written = writeByteBuffer(this.byteBuffer);
int total = buffer.remaining();
int written = writeByteBuffer(buffer);
if (logger.isTraceEnabled()) {
logger.trace("written: " + written + " total: " + total);

View File

@@ -25,6 +25,7 @@ import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.publisher.Operators;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -40,10 +41,12 @@ class WriteResultPublisher implements Publisher<Void> {
private final AtomicReference<State> state = new AtomicReference<>(State.UNSUBSCRIBED);
@Nullable
private Subscriber<? super Void> subscriber;
private volatile boolean publisherCompleted;
@Nullable
private volatile Throwable publisherError;
@@ -123,8 +126,11 @@ class WriteResultPublisher implements Publisher<Void> {
if (publisher.publisherCompleted) {
publisher.publishComplete();
}
else if (publisher.publisherError != null) {
publisher.publishError(publisher.publisherError);
else {
Throwable publisherError = publisher.publisherError;
if (publisherError != null) {
publisher.publishError(publisherError);
}
}
}
else {
@@ -149,12 +155,14 @@ class WriteResultPublisher implements Publisher<Void> {
@Override
void publishComplete(WriteResultPublisher publisher) {
if (publisher.changeState(this, COMPLETED)) {
Assert.state(publisher.subscriber != null, "No subscriber");
publisher.subscriber.onComplete();
}
}
@Override
void publishError(WriteResultPublisher publisher, Throwable t) {
if (publisher.changeState(this, COMPLETED)) {
Assert.state(publisher.subscriber != null, "No subscriber");
publisher.subscriber.onError(t);
}
}

View File

@@ -68,6 +68,7 @@ public class HessianClientInterceptor extends UrlBasedRemoteAccessor implements
private HessianProxyFactory proxyFactory = new HessianProxyFactory();
@Nullable
private Object hessianProxy;

View File

@@ -62,10 +62,13 @@ public class HessianExporter extends RemoteExporter implements InitializingBean
private SerializerFactory serializerFactory = new SerializerFactory();
@Nullable
private HessianRemoteResolver remoteResolver;
@Nullable
private Log debugLogger;
@Nullable
private HessianSkeleton skeleton;
@@ -212,10 +215,8 @@ public class HessianExporter extends RemoteExporter implements InitializingBean
throw new IOException("Expected 'H'/'C' (Hessian 2.0) or 'c' (Hessian 1.0) in hessian input at " + code);
}
if (this.serializerFactory != null) {
in.setSerializerFactory(this.serializerFactory);
out.setSerializerFactory(this.serializerFactory);
}
in.setSerializerFactory(this.serializerFactory);
out.setSerializerFactory(this.serializerFactory);
if (this.remoteResolver != null) {
in.setRemoteResolver(this.remoteResolver);
}

View File

@@ -73,6 +73,7 @@ public class HttpComponentsHttpInvokerRequestExecutor extends AbstractHttpInvoke
private HttpClient httpClient;
@Nullable
private RequestConfig requestConfig;

View File

@@ -73,8 +73,10 @@ import org.springframework.remoting.support.RemoteInvocationResult;
public class HttpInvokerClientInterceptor extends RemoteInvocationBasedAccessor
implements MethodInterceptor, HttpInvokerClientConfiguration {
@Nullable
private String codebaseUrl;
@Nullable
private HttpInvokerRequestExecutor httpInvokerRequestExecutor;
@@ -98,6 +100,7 @@ public class HttpInvokerClientInterceptor extends RemoteInvocationBasedAccessor
* Return the codebase URL to download classes from if not found locally.
*/
@Override
@Nullable
public String getCodebaseUrl() {
return this.codebaseUrl;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -33,6 +33,8 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Abstract exporter for JAX-WS services, autodetecting annotated service beans
@@ -50,14 +52,19 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
*/
public abstract class AbstractJaxWsServiceExporter implements BeanFactoryAware, InitializingBean, DisposableBean {
@Nullable
private Map<String, Object> endpointProperties;
@Nullable
private Executor executor;
@Nullable
private String bindingType;
@Nullable
private WebServiceFeature[] endpointFeatures;
@Nullable
private ListableBeanFactory beanFactory;
private final Set<Endpoint> publishedEndpoints = new LinkedHashSet<>();
@@ -127,11 +134,14 @@ public abstract class AbstractJaxWsServiceExporter implements BeanFactoryAware,
* @see #publishEndpoint
*/
public void publishEndpoints() {
Assert.state(this.beanFactory != null, "No BeanFactory set");
Set<String> beanNames = new LinkedHashSet<>(this.beanFactory.getBeanDefinitionCount());
beanNames.addAll(Arrays.asList(this.beanFactory.getBeanDefinitionNames()));
if (this.beanFactory instanceof ConfigurableBeanFactory) {
beanNames.addAll(Arrays.asList(((ConfigurableBeanFactory) this.beanFactory).getSingletonNames()));
}
for (String beanName : beanNames) {
try {
Class<?> type = this.beanFactory.getType(beanName);

View File

@@ -65,34 +65,46 @@ import org.springframework.util.StringUtils;
public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
implements MethodInterceptor, BeanClassLoaderAware, InitializingBean {
@Nullable
private Service jaxWsService;
@Nullable
private String portName;
@Nullable
private String username;
@Nullable
private String password;
@Nullable
private String endpointAddress;
private boolean maintainSession;
private boolean useSoapAction;
@Nullable
private String soapActionUri;
@Nullable
private Map<String, Object> customProperties;
@Nullable
private WebServiceFeature[] portFeatures;
@Nullable
private Class<?> serviceInterface;
private boolean lookupServiceOnStartup = true;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@Nullable
private QName portQName;
@Nullable
private Object portStub;
private final Object preparationMonitor = new Object();
@@ -286,6 +298,7 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
/**
* Return the interface of the service that this factory should create a proxy for.
*/
@Nullable
public Class<?> getServiceInterface() {
return this.serviceInterface;
}
@@ -312,6 +325,7 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
/**
* Return the bean ClassLoader to use for this interceptor.
*/
@Nullable
protected ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
@@ -402,6 +416,7 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
* @see #setPortName
* @see #getQName
*/
@Nullable
protected final QName getPortQName() {
return this.portQName;
}
@@ -472,6 +487,7 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
* Return the underlying JAX-WS port stub that this interceptor delegates to
* for each method invocation on the proxy.
*/
@Nullable
protected Object getPortStub() {
return this.portStub;
}
@@ -526,7 +542,7 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
* @see #getPortStub()
*/
@Nullable
protected Object doInvoke(MethodInvocation invocation, Object portStub) throws Throwable {
protected Object doInvoke(MethodInvocation invocation, @Nullable Object portStub) throws Throwable {
Method method = invocation.getMethod();
try {
return method.invoke(portStub, invocation.getArguments());

View File

@@ -44,16 +44,22 @@ import org.springframework.util.Assert;
*/
public class LocalJaxWsServiceFactory {
@Nullable
private URL wsdlDocumentUrl;
@Nullable
private String namespaceUri;
@Nullable
private String serviceName;
@Nullable
private WebServiceFeature[] serviceFeatures;
@Nullable
private Executor executor;
@Nullable
private HandlerResolver handlerResolver;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -20,6 +20,7 @@ import javax.xml.ws.Service;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
/**
* {@link org.springframework.beans.factory.FactoryBean} for locally
@@ -38,6 +39,7 @@ import org.springframework.beans.factory.InitializingBean;
public class LocalJaxWsServiceFactoryBean extends LocalJaxWsServiceFactory
implements FactoryBean<Service>, InitializingBean {
@Nullable
private Service service;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 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.
@@ -29,7 +29,9 @@ import com.sun.net.httpserver.HttpServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.lang.UsesSunHttpServer;
import org.springframework.util.Assert;
/**
* Simple exporter for JAX-WS services, autodetecting annotated service beans
@@ -53,10 +55,12 @@ public class SimpleHttpServerJaxWsServiceExporter extends AbstractJaxWsServiceEx
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private HttpServer server;
private int port = 8080;
@Nullable
private String hostname;
private int backlog = -1;
@@ -65,8 +69,10 @@ public class SimpleHttpServerJaxWsServiceExporter extends AbstractJaxWsServiceEx
private String basePath = "/";
@Nullable
private List<Filter> filters;
@Nullable
private Authenticator authenticator;
private boolean localServer = false;
@@ -157,11 +163,12 @@ public class SimpleHttpServerJaxWsServiceExporter extends AbstractJaxWsServiceEx
if (this.server == null) {
InetSocketAddress address = (this.hostname != null ?
new InetSocketAddress(this.hostname, this.port) : new InetSocketAddress(this.port));
this.server = HttpServer.create(address, this.backlog);
HttpServer server = HttpServer.create(address, this.backlog);
if (this.logger.isInfoEnabled()) {
this.logger.info("Starting HttpServer at address " + address);
}
this.server.start();
server.start();
this.server = server;
this.localServer = true;
}
super.afterPropertiesSet();
@@ -184,6 +191,7 @@ public class SimpleHttpServerJaxWsServiceExporter extends AbstractJaxWsServiceEx
* @return the fully populated HttpContext
*/
protected HttpContext buildHttpContext(Endpoint endpoint, String serviceName) {
Assert.state(this.server != null, "No HttpServer available");
String fullPath = calculateEndpointPath(endpoint, serviceName);
HttpContext httpContext = this.server.createContext(fullPath);
if (this.filters != null) {
@@ -209,7 +217,7 @@ public class SimpleHttpServerJaxWsServiceExporter extends AbstractJaxWsServiceEx
@Override
public void destroy() {
super.destroy();
if (this.localServer) {
if (this.server != null && this.localServer) {
logger.info("Stopping HttpServer");
this.server.stop(this.shutdownDelay);
}

View File

@@ -31,6 +31,7 @@ import org.springframework.lang.Nullable;
@SuppressWarnings("serial")
public class HttpMediaTypeNotSupportedException extends HttpMediaTypeException {
@Nullable
private final MediaType contentType;
@@ -67,6 +68,7 @@ public class HttpMediaTypeNotSupportedException extends HttpMediaTypeException {
/**
* Return the HTTP request content type method that caused the failure.
*/
@Nullable
public MediaType getContentType() {
return this.contentType;
}

View File

@@ -39,6 +39,7 @@ public class HttpRequestMethodNotSupportedException extends ServletException {
private String method;
@Nullable
private String[] supportedMethods;

View File

@@ -101,14 +101,18 @@ public class ContentNegotiationManagerFactoryBean
private boolean ignoreUnknownPathExtensions = true;
@Nullable
private Boolean useRegisteredExtensionsOnly;
private String parameterName = "format";
@Nullable
private ContentNegotiationStrategy defaultNegotiationStrategy;
@Nullable
private ContentNegotiationManager contentNegotiationManager;
@Nullable
private ServletContext servletContext;
@@ -268,13 +272,12 @@ public class ContentNegotiationManagerFactoryBean
}
public ContentNegotiationManager build() {
afterPropertiesSet();
return this.contentNegotiationManager;
}
@Override
public void afterPropertiesSet() {
build();
}
public ContentNegotiationManager build() {
List<ContentNegotiationStrategy> strategies = new ArrayList<>();
if (this.favorPathExtension) {
@@ -309,8 +312,10 @@ public class ContentNegotiationManagerFactoryBean
}
this.contentNegotiationManager = new ContentNegotiationManager(strategies);
return this.contentNegotiationManager;
}
@Override
public ContentNegotiationManager getObject() {
return this.contentNegotiationManager;

View File

@@ -17,7 +17,6 @@
package org.springframework.web.accept;
import java.util.Map;
import javax.servlet.ServletContext;
import org.springframework.core.io.Resource;
@@ -72,11 +71,9 @@ public class ServletPathExtensionContentNegotiationStrategy extends PathExtensio
throws HttpMediaTypeNotAcceptableException {
MediaType mediaType = null;
if (this.servletContext != null) {
String mimeType = this.servletContext.getMimeType("file." + extension);
if (StringUtils.hasText(mimeType)) {
mediaType = MediaType.parseMediaType(mimeType);
}
String mimeType = this.servletContext.getMimeType("file." + extension);
if (StringUtils.hasText(mimeType)) {
mediaType = MediaType.parseMediaType(mimeType);
}
if (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
MediaType superMediaType = super.handleNoMatch(webRequest, extension);
@@ -98,11 +95,9 @@ public class ServletPathExtensionContentNegotiationStrategy extends PathExtensio
@Override
public MediaType getMediaTypeForResource(Resource resource) {
MediaType mediaType = null;
if (this.servletContext != null) {
String mimeType = this.servletContext.getMimeType(resource.getFilename());
if (StringUtils.hasText(mimeType)) {
mediaType = MediaType.parseMediaType(mimeType);
}
String mimeType = this.servletContext.getMimeType(resource.getFilename());
if (StringUtils.hasText(mimeType)) {
mediaType = MediaType.parseMediaType(mimeType);
}
if (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
MediaType superMediaType = super.getMediaTypeForResource(resource);

View File

@@ -75,7 +75,7 @@ public class ServletRequestDataBinder extends WebDataBinder {
* if the binder is just used to convert a plain parameter value)
* @param objectName the name of the target object
*/
public ServletRequestDataBinder(@Nullable Object target, @Nullable String objectName) {
public ServletRequestDataBinder(@Nullable Object target, String objectName) {
super(target, objectName);
}

View File

@@ -98,7 +98,7 @@ public class WebDataBinder extends DataBinder {
* if the binder is just used to convert a plain parameter value)
* @param objectName the name of the target object
*/
public WebDataBinder(@Nullable Object target, @Nullable String objectName) {
public WebDataBinder(@Nullable Object target, String objectName) {
super(target, objectName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -44,14 +44,19 @@ public class ConfigurableWebBindingInitializer implements WebBindingInitializer
private boolean directFieldAccess = false;
@Nullable
private MessageCodesResolver messageCodesResolver;
@Nullable
private BindingErrorProcessor bindingErrorProcessor;
@Nullable
private Validator validator;
@Nullable
private ConversionService conversionService;
@Nullable
private PropertyEditorRegistrar[] propertyEditorRegistrars;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -29,6 +29,7 @@ import org.springframework.web.context.request.NativeWebRequest;
*/
public class DefaultDataBinderFactory implements WebDataBinderFactory {
@Nullable
private final WebBindingInitializer initializer;
@@ -49,8 +50,8 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
*/
@Override
@SuppressWarnings("deprecation")
public final WebDataBinder createBinder(NativeWebRequest webRequest, @Nullable Object target,
@Nullable String objectName) throws Exception {
public final WebDataBinder createBinder(
NativeWebRequest webRequest, @Nullable Object target, String objectName) throws Exception {
WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest);
if (this.initializer != null) {
@@ -69,7 +70,7 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
* @throws Exception in case of invalid state or arguments
*/
protected WebDataBinder createBinderInstance(
@Nullable Object target, @Nullable String objectName, NativeWebRequest webRequest) throws Exception {
@Nullable Object target, String objectName, NativeWebRequest webRequest) throws Exception {
return new WebRequestDataBinder(target, objectName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -31,11 +31,13 @@ public interface WebDataBinderFactory {
/**
* Create a {@link WebDataBinder} for the given object.
* @param webRequest the current request
* @param target the object to create a data binder for, or {@code null} if creating a binder for a simple type
* @param target the object to create a data binder for,
* or {@code null} if creating a binder for a simple type
* @param objectName the name of the target object
* @return the created {@link WebDataBinder} instance, never null
* @throws Exception raised if the creation and initialization of the data binder fails
*/
WebDataBinder createBinder(NativeWebRequest webRequest, @Nullable Object target, @Nullable String objectName) throws Exception;
WebDataBinder createBinder(NativeWebRequest webRequest, @Nullable Object target, String objectName)
throws Exception;
}

View File

@@ -41,7 +41,6 @@ import org.springframework.web.server.ServerWebExchange;
*/
public class WebExchangeDataBinder extends WebDataBinder {
/**
* Create a new instance, with default object name.
* @param target the target object to bind onto (or {@code null} if the
@@ -86,12 +85,10 @@ public class WebExchangeDataBinder extends WebDataBinder {
* Combine query params and form data for multipart form data from the body
* of the request into a {@code Map<String, Object>} of values to use for
* data binding purposes.
*
* @param exchange the current exchange
* @return a {@code Mono} with the values to bind
*/
public static Mono<Map<String, Object>> extractValuesToBind(ServerWebExchange exchange) {
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
Mono<MultiValueMap<String, String>> formData = exchange.getFormData();
Mono<MultiValueMap<String, Part>> multipartData = exchange.getMultipartData();

View File

@@ -86,7 +86,7 @@ public class WebRequestDataBinder extends WebDataBinder {
* if the binder is just used to convert a plain parameter value)
* @param objectName the name of the target object
*/
public WebRequestDataBinder(@Nullable Object target, @Nullable String objectName) {
public WebRequestDataBinder(@Nullable Object target, String objectName) {
super(target, objectName);
}

View File

@@ -593,6 +593,7 @@ public class AsyncRestTemplate extends org.springframework.http.client.support.I
private final URI url;
@Nullable
private final ResponseExtractor<T> responseExtractor;
public ResponseExtractorFuture(HttpMethod method, URI url,

View File

@@ -28,6 +28,7 @@ import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -42,6 +43,7 @@ public class HttpMessageConverterExtractor<T> implements ResponseExtractor<T> {
private final Type responseType;
@Nullable
private final Class<T> responseClass;
private final List<HttpMessageConverter<?>> messageConverters;

View File

@@ -23,6 +23,7 @@ import java.io.PushbackInputStream;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.lang.Nullable;
/**
* Implementation of {@link ClientHttpResponse} that can not only check if
@@ -31,12 +32,13 @@ import org.springframework.http.client.ClientHttpResponse;
*
* @author Brian Clozel
* @since 4.1.5
* @see <a href="http://tools.ietf.org/html/rfc7230#section-3.3.3">rfc7230 Section 3.3.3</a>
* @see <a href="http://tools.ietf.org/html/rfc7230#section-3.3.3">RFC 7230 Section 3.3.3</a>
*/
class MessageBodyClientHttpResponseWrapper implements ClientHttpResponse {
private final ClientHttpResponse response;
@Nullable
private PushbackInputStream pushbackInputStream;

View File

@@ -42,8 +42,10 @@ public class RestClientResponseException extends RestClientException {
private final byte[] responseBody;
@Nullable
private final HttpHeaders responseHeaders;
@Nullable
private final String responseCharset;
@@ -84,6 +86,7 @@ public class RestClientResponseException extends RestClientException {
/**
* Return the HTTP response headers.
*/
@Nullable
public HttpHeaders getResponseHeaders() {
return this.responseHeaders;
}

View File

@@ -783,6 +783,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
*/
private class AcceptHeaderRequestCallback implements RequestCallback {
@Nullable
private final Type responseType;
private AcceptHeaderRequestCallback(@Nullable Type responseType) {
@@ -937,6 +938,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
*/
private class ResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {
@Nullable
private final HttpMessageConverterExtractor<T> delegate;
public ResponseEntityResponseExtractor(@Nullable Type responseType) {

View File

@@ -158,12 +158,14 @@ public class ContextLoader {
* The 'current' WebApplicationContext, if the ContextLoader class is
* deployed in the web app ClassLoader itself.
*/
@Nullable
private static volatile WebApplicationContext currentContext;
/**
* The root WebApplicationContext instance that this loader manages.
*/
@Nullable
private WebApplicationContext context;
/** Actual ApplicationContextInitializer instances to apply to the context */

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -62,8 +62,10 @@ public class ServletRequestAttributes extends AbstractRequestAttributes {
private final HttpServletRequest request;
@Nullable
private HttpServletResponse response;
@Nullable
private volatile HttpSession session;
private final Map<String, Object> sessionAttributesToUpdate = new ConcurrentHashMap<>(1);

View File

@@ -24,9 +24,11 @@ import org.springframework.context.support.AbstractRefreshableConfigApplicationC
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.lang.Nullable;
import org.springframework.ui.context.Theme;
import org.springframework.ui.context.ThemeSource;
import org.springframework.ui.context.support.UiApplicationContextUtils;
import org.springframework.util.Assert;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.ConfigurableWebEnvironment;
import org.springframework.web.context.ServletConfigAware;
@@ -80,15 +82,19 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
implements ConfigurableWebApplicationContext, ThemeSource {
/** Servlet context that this context runs in */
@Nullable
private ServletContext servletContext;
/** Servlet config that this context runs in, if any */
@Nullable
private ServletConfig servletConfig;
/** Namespace of this context, or {@code null} if root */
@Nullable
private String namespace;
/** the ThemeSource for this ApplicationContext */
@Nullable
private ThemeSource themeSource;
@@ -103,6 +109,7 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
}
@Override
@Nullable
public ServletContext getServletContext() {
return this.servletContext;
}
@@ -116,6 +123,7 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
}
@Override
@Nullable
public ServletConfig getServletConfig() {
return this.servletConfig;
}
@@ -127,6 +135,7 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
}
@Override
@Nullable
public String getNamespace() {
return this.namespace;
}
@@ -169,6 +178,7 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
*/
@Override
protected Resource getResourceByPath(String path) {
Assert.state(this.servletContext != null, "No ServletContext available");
return new ServletContextResource(this.servletContext, path);
}
@@ -203,6 +213,7 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
@Override
public Theme getTheme(String themeName) {
Assert.state(this.themeSource != null, "No ThemeSource available");
return this.themeSource.getTheme(themeName);
}

View File

@@ -37,8 +37,10 @@ public class ContextExposingHttpServletRequest extends HttpServletRequestWrapper
private final WebApplicationContext webApplicationContext;
@Nullable
private final Set<String> exposedContextBeanNames;
@Nullable
private Set<String> explicitAttributes;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 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.
@@ -29,6 +29,7 @@ import org.springframework.lang.Nullable;
import org.springframework.ui.context.Theme;
import org.springframework.ui.context.ThemeSource;
import org.springframework.ui.context.support.UiApplicationContextUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ConfigurableWebApplicationContext;
@@ -64,8 +65,10 @@ import org.springframework.web.context.ServletContextAware;
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
@Nullable
private ServletContext servletContext;
@Nullable
private ThemeSource themeSource;
@@ -122,6 +125,7 @@ public class GenericWebApplicationContext extends GenericApplicationContext
}
@Override
@Nullable
public ServletContext getServletContext() {
return this.servletContext;
}
@@ -145,9 +149,10 @@ public class GenericWebApplicationContext extends GenericApplicationContext
*/
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
@@ -158,6 +163,7 @@ public class GenericWebApplicationContext extends GenericApplicationContext
*/
@Override
protected Resource getResourceByPath(String path) {
Assert.state(this.servletContext != null, "No ServletContext available");
return new ServletContextResource(this.servletContext, path);
}
@@ -192,6 +198,7 @@ public class GenericWebApplicationContext extends GenericApplicationContext
@Override
public Theme getTheme(String themeName) {
Assert.state(this.themeSource != null, "No ThemeSource available");
return this.themeSource.getTheme(themeName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -38,15 +38,18 @@ import org.springframework.lang.Nullable;
public class RequestHandledEvent extends ApplicationEvent {
/** Session id that applied to the request, if any */
@Nullable
private String sessionId;
/** Usually the UserPrincipal */
@Nullable
private String userName;
/** Request processing time */
private final long processingTimeMillis;
/** Cause of failure, if any */
@Nullable
private Throwable failureCause;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -19,6 +19,7 @@ package org.springframework.web.context.support;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.web.context.ServletContextAware;
/**
@@ -43,8 +44,10 @@ import org.springframework.web.context.ServletContextAware;
*/
public class ServletContextAttributeFactoryBean implements FactoryBean<Object>, ServletContextAware {
@Nullable
private String attributeName;
@Nullable
private Object attribute;

View File

@@ -41,8 +41,10 @@ import org.springframework.web.context.ServletContextAware;
*/
public class ServletContextAwareProcessor implements BeanPostProcessor {
@Nullable
private ServletContext servletContext;
@Nullable
private ServletConfig servletConfig;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -19,6 +19,7 @@ package org.springframework.web.context.support;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.web.context.ServletContextAware;
/**
@@ -38,8 +39,10 @@ import org.springframework.web.context.ServletContextAware;
*/
public class ServletContextParameterFactoryBean implements FactoryBean<String>, ServletContextAware {
@Nullable
private String initParamName;
@Nullable
private String paramValue;

View File

@@ -24,9 +24,11 @@ import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.lang.Nullable;
import org.springframework.ui.context.Theme;
import org.springframework.ui.context.ThemeSource;
import org.springframework.ui.context.support.UiApplicationContextUtils;
import org.springframework.util.Assert;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.ServletConfigAware;
import org.springframework.web.context.ServletContextAware;
@@ -56,12 +58,16 @@ import org.springframework.web.context.ServletContextAware;
public class StaticWebApplicationContext extends StaticApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
@Nullable
private ServletContext servletContext;
@Nullable
private ServletConfig servletConfig;
@Nullable
private String namespace;
@Nullable
private ThemeSource themeSource;
@@ -79,6 +85,7 @@ public class StaticWebApplicationContext extends StaticApplicationContext
}
@Override
@Nullable
public ServletContext getServletContext() {
return this.servletContext;
}
@@ -92,6 +99,7 @@ public class StaticWebApplicationContext extends StaticApplicationContext
}
@Override
@Nullable
public ServletConfig getServletConfig() {
return this.servletConfig;
}
@@ -103,6 +111,7 @@ public class StaticWebApplicationContext extends StaticApplicationContext
}
@Override
@Nullable
public String getNamespace() {
return this.namespace;
}
@@ -150,6 +159,7 @@ public class StaticWebApplicationContext extends StaticApplicationContext
*/
@Override
protected Resource getResourceByPath(String path) {
Assert.state(this.servletContext != null, "No ServletContext available");
return new ServletContextResource(this.servletContext, path);
}
@@ -186,6 +196,7 @@ public class StaticWebApplicationContext extends StaticApplicationContext
@Override
public Theme getTheme(String themeName) {
Assert.state(this.themeSource != null, "No ThemeSource available");
return this.themeSource.getTheme(themeName);
}

View File

@@ -205,7 +205,7 @@ public abstract class WebApplicationContextUtils {
* @param bf the BeanFactory to configure
* @param sc the ServletContext that we're running within
*/
public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf, ServletContext sc) {
public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf, @Nullable ServletContext sc) {
registerEnvironmentBeans(bf, sc, null);
}

View File

@@ -42,6 +42,7 @@ import org.springframework.web.util.WebUtils;
*/
public abstract class WebApplicationObjectSupport extends ApplicationObjectSupport implements ServletContextAware {
@Nullable
private ServletContext servletContext;

View File

@@ -65,18 +65,25 @@ public class CorsConfiguration {
}
@Nullable
private List<String> allowedOrigins;
@Nullable
private List<String> allowedMethods;
@Nullable
private List<HttpMethod> resolvedMethods = DEFAULT_METHODS;
@Nullable
private List<String> allowedHeaders;
@Nullable
private List<String> exposedHeaders;
@Nullable
private Boolean allowCredentials;
@Nullable
private Long maxAge;

View File

@@ -17,7 +17,6 @@
package org.springframework.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
@@ -82,14 +81,18 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
*/
public class DelegatingFilterProxy extends GenericFilterBean {
@Nullable
private String contextAttribute;
@Nullable
private WebApplicationContext webApplicationContext;
@Nullable
private String targetBeanName;
private boolean targetFilterLifecycle = false;
@Nullable
private volatile Filter delegate;
private final Object delegateMonitor = new Object();
@@ -117,7 +120,7 @@ public class DelegatingFilterProxy extends GenericFilterBean {
* @see #setEnvironment(org.springframework.core.env.Environment)
*/
public DelegatingFilterProxy(Filter delegate) {
Assert.notNull(delegate, "delegate Filter object must not be null");
Assert.notNull(delegate, "Delegate Filter must not be null");
this.delegate = delegate;
}
@@ -197,6 +200,7 @@ public class DelegatingFilterProxy extends GenericFilterBean {
/**
* Return the name of the target bean in the Spring application context.
*/
@Nullable
protected String getTargetBeanName() {
return this.targetBeanName;
}
@@ -249,15 +253,16 @@ public class DelegatingFilterProxy extends GenericFilterBean {
Filter delegateToUse = this.delegate;
if (delegateToUse == null) {
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
delegateToUse = this.delegate;
if (delegateToUse == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: " +
"no ContextLoaderListener or DispatcherServlet registered?");
}
this.delegate = initDelegate(wac);
delegateToUse = initDelegate(wac);
}
delegateToUse = this.delegate;
this.delegate = delegateToUse;
}
}
@@ -327,7 +332,9 @@ public class DelegatingFilterProxy extends GenericFilterBean {
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
String targetBeanName = getTargetBeanName();
Assert.state(targetBeanName != null, "No target bean name set");
Filter delegate = wac.getBean(targetBeanName, Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
}

View File

@@ -187,10 +187,12 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
*/
private static class ForwardedHeaderExtractingRequest extends ForwardedHeaderRemovingRequest {
@Nullable
private final String scheme;
private final boolean secure;
@Nullable
private final String host;
private final int port;
@@ -238,11 +240,13 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
}
@Override
@Nullable
public String getScheme() {
return this.scheme;
}
@Override
@Nullable
public String getServerName() {
return this.host;
}

View File

@@ -84,12 +84,16 @@ public abstract class GenericFilterBean implements Filter, BeanNameAware, Enviro
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private String beanName;
@Nullable
private Environment environment;
@Nullable
private ServletContext servletContext;
@Nullable
private FilterConfig filterConfig;
private final Set<String> requiredProperties = new HashSet<>(4);

View File

@@ -54,6 +54,7 @@ public class ControllerAdviceBean implements Ordered {
private final Object bean;
@Nullable
private final BeanFactory beanFactory;
private final int order;
@@ -137,7 +138,7 @@ public class ControllerAdviceBean implements Ordered {
@Nullable
public Class<?> getBeanType() {
Class<?> beanType = (this.bean instanceof String ?
this.beanFactory.getType((String) this.bean) : this.bean.getClass());
obtainBeanFactory().getType((String) this.bean) : this.bean.getClass());
return (beanType != null ? ClassUtils.getUserClass(beanType) : null);
}
@@ -145,7 +146,12 @@ public class ControllerAdviceBean implements Ordered {
* Return a bean instance if necessary resolving the bean name through the BeanFactory.
*/
public Object resolveBean() {
return (this.bean instanceof String ? this.beanFactory.getBean((String) this.bean) : this.bean);
return (this.bean instanceof String ? obtainBeanFactory().getBean((String) this.bean) : this.bean);
}
private BeanFactory obtainBeanFactory() {
Assert.state(this.beanFactory != null, "No BeanFactory set");
return this.beanFactory;
}
/**

View File

@@ -58,6 +58,7 @@ public class HandlerMethod {
private final Object bean;
@Nullable
private final BeanFactory beanFactory;
private final Class<?> beanType;
@@ -118,7 +119,10 @@ public class HandlerMethod {
this.bean = beanName;
this.beanFactory = beanFactory;
Class<?> beanType = beanFactory.getType(beanName);
this.beanType = (beanType != null ? ClassUtils.getUserClass(beanType) : null);
if (beanType == null) {
throw new IllegalStateException("Cannot resolve bean type for bean with name '" + beanName + "'");
}
this.beanType = ClassUtils.getUserClass(beanType);
this.method = method;
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
this.parameters = initMethodParameters();
@@ -301,6 +305,7 @@ public class HandlerMethod {
public HandlerMethod createWithResolvedBean() {
Object handler = this.bean;
if (this.bean instanceof String) {
Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory");
String beanName = (String) this.bean;
handler = this.beanFactory.getBean(beanName);
}
@@ -380,6 +385,7 @@ public class HandlerMethod {
*/
private class ReturnValueMethodParameter extends HandlerMethodParameter {
@Nullable
private final Object returnValue;
public ReturnValueMethodParameter(@Nullable Object returnValue) {

View File

@@ -63,8 +63,10 @@ import org.springframework.web.method.support.ModelAndViewContainer;
*/
public abstract class AbstractNamedValueMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Nullable
private final ConfigurableBeanFactory configurableBeanFactory;
@Nullable
private final BeanExpressionContext expressionContext;
private final Map<MethodParameter, NamedValueInfo> namedValueInfoCache = new ConcurrentHashMap<>(256);
@@ -268,6 +270,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
private final boolean required;
@Nullable
private final String defaultValue;
public NamedValueInfo(String name, boolean required, @Nullable String defaultValue) {

View File

@@ -22,14 +22,13 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.ExceptionDepthComparator;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -50,17 +49,10 @@ public class ExceptionHandlerMethodResolver {
public static final MethodFilter EXCEPTION_HANDLER_METHODS = method ->
(AnnotationUtils.findAnnotation(method, ExceptionHandler.class) != null);
/**
* Arbitrary {@link Method} reference, indicating no method found in the cache.
*/
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis");
private final Map<Class<? extends Throwable>, Method> mappedMethods = new ConcurrentReferenceHashMap<>(16);
private final Map<Class<? extends Throwable>, Method> mappedMethods =
new ConcurrentHashMap<>(16);
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache =
new ConcurrentHashMap<>(16);
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache = new ConcurrentReferenceHashMap<>(16);
/**
@@ -157,9 +149,9 @@ public class ExceptionHandlerMethodResolver {
Method method = this.exceptionLookupCache.get(exceptionType);
if (method == null) {
method = getMappedMethod(exceptionType);
this.exceptionLookupCache.put(exceptionType, (method != null ? method : NO_METHOD_FOUND));
this.exceptionLookupCache.put(exceptionType, method);
}
return (method != NO_METHOD_FOUND ? method : null);
return method;
}
/**

Some files were not shown because too many files have changed in this diff Show More