Polishing

This commit is contained in:
Juergen Hoeller 2017-08-08 17:27:28 +02:00
parent 09f5c71374
commit adeb521ce4
8 changed files with 54 additions and 39 deletions

View File

@ -238,6 +238,7 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/**
* Return whether this a <b>Prototype</b>, with an independent instance
* returned for each call.
* @since 3.0
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();

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.
@ -36,8 +36,7 @@ public class DestroyMethodInferenceTests {
@Test
public void beanMethods() {
ConfigurableApplicationContext ctx =
new AnnotationConfigApplicationContext(Config.class);
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
WithExplicitDestroyMethod c0 = ctx.getBean(WithExplicitDestroyMethod.class);
WithLocalCloseMethod c1 = ctx.getBean("c1", WithLocalCloseMethod.class);
WithLocalCloseMethod c2 = ctx.getBean("c2", WithLocalCloseMethod.class);
@ -91,9 +90,11 @@ public class DestroyMethodInferenceTests {
assertThat(x8.closed, is(false));
}
@Configuration
static class Config {
@Bean(destroyMethod="explicitClose")
@Bean(destroyMethod = "explicitClose")
public WithExplicitDestroyMethod c0() {
return new WithExplicitDestroyMethod();
}
@ -118,12 +119,12 @@ public class DestroyMethodInferenceTests {
return new WithInheritedCloseMethod();
}
@Bean(destroyMethod="other")
@Bean(destroyMethod = "other")
public WithInheritedCloseMethod c5() {
return new WithInheritedCloseMethod() {
@Override
public void close() throws IOException {
throw new RuntimeException("close() should not be called");
throw new IllegalStateException("close() should not be called");
}
@SuppressWarnings("unused")
public void other() {
@ -150,33 +151,46 @@ public class DestroyMethodInferenceTests {
static class WithExplicitDestroyMethod {
boolean closed = false;
public void explicitClose() {
closed = true;
}
}
static class WithLocalCloseMethod {
boolean closed = false;
public void close() {
closed = true;
}
}
static class WithInheritedCloseMethod implements Closeable {
boolean closed = false;
@Override
public void close() throws IOException {
closed = true;
}
}
static class WithNoCloseMethod {
boolean closed = false;
}
static class WithLocalShutdownMethod {
boolean closed = false;
public void shutdown() {
closed = true;
}

View File

@ -268,7 +268,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
}
@Override
public void setSubscriptionId(String subscriptionId) {
public void setSubscriptionId(@Nullable String subscriptionId) {
super.setSubscriptionId(subscriptionId);
trySetStompHeaderForSubscriptionId();
}

View File

@ -58,9 +58,7 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
private static URI initUri(HttpServerRequest request) throws URISyntaxException {
Assert.notNull(request, "'request' must not be null");
URI baseUri = resolveBaseUrl(request);
String requestUri = request.uri();
return (baseUri != null ? new URI(baseUri.toString() + requestUri) : new URI(requestUri));
return new URI(resolveBaseUrl(request).toString() + request.uri());
}
private static URI resolveBaseUrl(HttpServerRequest request) throws URISyntaxException {
@ -69,14 +67,16 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
final int portIndex;
if (header.startsWith("[")) {
portIndex = header.indexOf(':', header.indexOf(']'));
} else {
}
else {
portIndex = header.indexOf(':');
}
if (portIndex != -1) {
try {
return new URI(null, null, header.substring(0, portIndex),
Integer.parseInt(header.substring(portIndex + 1)), null, null, null);
} catch (NumberFormatException ignore) {
}
catch (NumberFormatException ex) {
throw new URISyntaxException(header, "Unable to parse port", portIndex);
}
}

View File

@ -45,10 +45,23 @@ import org.springframework.web.context.request.NativeWebRequest;
*/
public interface CallableProcessingInterceptor {
/**
* Constant indicating that no result has been determined by this
* interceptor, giving subsequent interceptors a chance.
* @see #handleTimeout
* @see #handleError
*/
Object RESULT_NONE = new Object();
/**
* Constant indicating that the response has been handled by this interceptor
* without a result and that no further interceptors are to be invoked.
* @see #handleTimeout
* @see #handleError
*/
Object RESPONSE_HANDLED = new Object();
/**
* Invoked <em>before</em> the start of concurrent handling in the original
* thread in which the {@code Callable} is submitted for concurrent handling.
@ -58,6 +71,7 @@ public interface CallableProcessingInterceptor {
* {@link #preProcess(NativeWebRequest, Callable)}. Capturing the state of
* Spring Security's SecurityContextHolder and migrating it to the new Thread
* is a concrete example of where this is useful.
* <p>The default implementation is empty.
* @param request the current request
* @param task the task for the current async request
* @throws Exception in case of errors
@ -69,6 +83,7 @@ public interface CallableProcessingInterceptor {
* Invoked <em>after</em> the start of concurrent handling in the async
* thread in which the {@code Callable} is executed and <em>before</em> the
* actual invocation of the {@code Callable}.
* <p>The default implementation is empty.
* @param request the current request
* @param task the task for the current async request
* @throws Exception in case of errors
@ -81,6 +96,7 @@ public interface CallableProcessingInterceptor {
* async thread in which the {@code Callable} is executed. This method may
* be invoked later than {@code afterTimeout} or {@code afterCompletion}
* depending on when the {@code Callable} finishes processing.
* <p>The default implementation is empty.
* @param request the current request
* @param task the task for the current async request
* @param concurrentResult the result of concurrent processing, which could
@ -96,6 +112,7 @@ public interface CallableProcessingInterceptor {
* the {@code Callable} task completes. Implementations may return a value,
* including an {@link Exception}, to use instead of the value the
* {@link Callable} did not return in time.
* <p>The default implementation always returns {@link #RESULT_NONE}.
* @param request the current request
* @param task the task for the current async request
* @return a concurrent result value; if the value is anything other than
@ -112,6 +129,7 @@ public interface CallableProcessingInterceptor {
* the async request before the {@code Callable} task completes.
* Implementations may return a value, including an {@link Exception}, to
* use instead of the value the {@link Callable} did not return in time.
* <p>The default implementation always returns {@link #RESULT_NONE}.
* @param request the current request
* @param task the task for the current async request
* @param t the error that occurred while request processing
@ -128,6 +146,7 @@ public interface CallableProcessingInterceptor {
/**
* Invoked from a container thread when async processing completes for any
* reason including timeout or network error.
* <p>The default implementation is empty.
* @param request the current request
* @param task the task for the current async request
* @throws Exception in case of errors

View File

@ -32,48 +32,28 @@ import org.springframework.web.context.request.NativeWebRequest;
@Deprecated
public abstract class CallableProcessingInterceptorAdapter implements CallableProcessingInterceptor {
/**
* This implementation is empty.
*/
@Override
public <T> void beforeConcurrentHandling(NativeWebRequest request, Callable<T> task) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public <T> void preProcess(NativeWebRequest request, Callable<T> task) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public <T> void postProcess(NativeWebRequest request, Callable<T> task, Object concurrentResult) throws Exception {
}
/**
* This implementation always returns
* {@link CallableProcessingInterceptor#RESULT_NONE RESULT_NONE}.
*/
@Override
public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception {
return RESULT_NONE;
}
/**
* This implementation always returns
* {@link CallableProcessingInterceptor#RESULT_NONE RESULT_NONE}.
*/
@Override
public <T> Object handleError(NativeWebRequest request, Callable<T> task, Throwable t) throws Exception {
return RESULT_NONE;
}
/**
* This implementation is empty.
*/
@Override
public <T> void afterCompletion(NativeWebRequest request, Callable<T> task) throws Exception {
}

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 java.net.URI;
import java.time.Duration;
import org.hamcrest.Matchers;
import org.junit.Ignore;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@ -32,7 +33,7 @@ import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.*;
/**
* @author Stephane Maldini
@ -44,12 +45,14 @@ public class AsyncIntegrationTests extends AbstractHttpHandlerIntegrationTests {
private final DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
@Override
protected AsyncHandler createHttpHandler() {
return new AsyncHandler();
}
@Test
@Ignore // TODO: fragile due to socket failures
public void basicTest() throws Exception {
URI url = new URI("http://localhost:" + port);
ResponseEntity<String> response = new RestTemplate().exchange(
@ -58,6 +61,7 @@ public class AsyncIntegrationTests extends AbstractHttpHandlerIntegrationTests {
assertThat(response.getBody(), Matchers.equalTo("hello"));
}
private class AsyncHandler implements HttpHandler {
@Override

View File

@ -24,7 +24,6 @@ import java.util.function.Consumer;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.WebExceptionHandler;
@ -49,8 +48,7 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
private final List<WebExceptionHandler> exceptionHandlers = new ArrayList<>();
@Nullable
private LocaleContextResolver localeContextResolver;
private LocaleContextResolver localeContextResolver = new AcceptHeaderLocaleContextResolver();
public DefaultHandlerStrategiesBuilder() {
@ -119,7 +117,6 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
private final List<WebExceptionHandler> exceptionHandlers;
@Nullable
private final LocaleContextResolver localeContextResolver;
public DefaultHandlerStrategies(
@ -128,7 +125,7 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
List<ViewResolver> viewResolvers,
List<WebFilter> webFilters,
List<WebExceptionHandler> exceptionHandlers,
@Nullable LocaleContextResolver localeContextResolver) {
LocaleContextResolver localeContextResolver) {
this.messageReaders = unmodifiableCopy(messageReaders);
this.messageWriters = unmodifiableCopy(messageWriters);