WebHttpHandlerBuilder retains ApplicationContext in copy constructor

Issue: SPR-16972
This commit is contained in:
Juergen Hoeller 2018-06-25 18:12:12 +02:00
parent 853d30df26
commit 2a15962d7f
2 changed files with 25 additions and 31 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -79,6 +79,9 @@ public class WebHttpHandlerBuilder {
private final WebHandler webHandler; private final WebHandler webHandler;
@Nullable
private final ApplicationContext applicationContext;
private final List<WebFilter> filters = new ArrayList<>(); private final List<WebFilter> filters = new ArrayList<>();
private final List<WebExceptionHandler> exceptionHandlers = new ArrayList<>(); private final List<WebExceptionHandler> exceptionHandlers = new ArrayList<>();
@ -92,22 +95,11 @@ public class WebHttpHandlerBuilder {
@Nullable @Nullable
private LocaleContextResolver localeContextResolver; private LocaleContextResolver localeContextResolver;
@Nullable
private ApplicationContext applicationContext;
/**
* Private constructor.
*/
private WebHttpHandlerBuilder(WebHandler webHandler) {
Assert.notNull(webHandler, "WebHandler must not be null");
this.webHandler = webHandler;
}
/** /**
* Private constructor to use when initialized from an ApplicationContext. * Private constructor to use when initialized from an ApplicationContext.
*/ */
private WebHttpHandlerBuilder(WebHandler webHandler, ApplicationContext applicationContext) { private WebHttpHandlerBuilder(WebHandler webHandler, @Nullable ApplicationContext applicationContext) {
Assert.notNull(webHandler, "WebHandler must not be null"); Assert.notNull(webHandler, "WebHandler must not be null");
this.webHandler = webHandler; this.webHandler = webHandler;
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
@ -118,6 +110,7 @@ public class WebHttpHandlerBuilder {
*/ */
private WebHttpHandlerBuilder(WebHttpHandlerBuilder other) { private WebHttpHandlerBuilder(WebHttpHandlerBuilder other) {
this.webHandler = other.webHandler; this.webHandler = other.webHandler;
this.applicationContext = other.applicationContext;
this.filters.addAll(other.filters); this.filters.addAll(other.filters);
this.exceptionHandlers.addAll(other.exceptionHandlers); this.exceptionHandlers.addAll(other.exceptionHandlers);
this.sessionManager = other.sessionManager; this.sessionManager = other.sessionManager;
@ -132,7 +125,7 @@ public class WebHttpHandlerBuilder {
* @return the prepared builder * @return the prepared builder
*/ */
public static WebHttpHandlerBuilder webHandler(WebHandler webHandler) { public static WebHttpHandlerBuilder webHandler(WebHandler webHandler) {
return new WebHttpHandlerBuilder(webHandler); return new WebHttpHandlerBuilder(webHandler, null);
} }
/** /**
@ -156,7 +149,6 @@ public class WebHttpHandlerBuilder {
* @return the prepared builder * @return the prepared builder
*/ */
public static WebHttpHandlerBuilder applicationContext(ApplicationContext context) { public static WebHttpHandlerBuilder applicationContext(ApplicationContext context) {
WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder( WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder(
context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class), context); context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class), context);
@ -272,13 +264,10 @@ public class WebHttpHandlerBuilder {
* Build the {@link HttpHandler}. * Build the {@link HttpHandler}.
*/ */
public HttpHandler build() { public HttpHandler build() {
WebHandler decorated = new FilteringWebHandler(this.webHandler, this.filters);
WebHandler decorated;
decorated = new FilteringWebHandler(this.webHandler, this.filters);
decorated = new ExceptionHandlingWebHandler(decorated, this.exceptionHandlers); decorated = new ExceptionHandlingWebHandler(decorated, this.exceptionHandlers);
HttpWebHandlerAdapter adapted = new HttpWebHandlerAdapter(decorated); HttpWebHandlerAdapter adapted = new HttpWebHandlerAdapter(decorated);
if (this.sessionManager != null) { if (this.sessionManager != null) {
adapted.setSessionManager(this.sessionManager); adapted.setSessionManager(this.sessionManager);
} }
@ -291,7 +280,6 @@ public class WebHttpHandlerBuilder {
if (this.applicationContext != null) { if (this.applicationContext != null) {
adapted.setApplicationContext(this.applicationContext); adapted.setApplicationContext(this.applicationContext);
} }
adapted.afterPropertiesSet(); adapted.afterPropertiesSet();
return adapted; return adapted;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,10 +36,8 @@ import org.springframework.web.server.WebExceptionHandler;
import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebHandler; import org.springframework.web.server.WebHandler;
import static java.time.Duration.ofMillis; import static java.time.Duration.*;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/** /**
* Unit tests for {@link WebHttpHandlerBuilder}. * Unit tests for {@link WebHttpHandlerBuilder}.
@ -48,13 +46,12 @@ import static org.junit.Assert.assertTrue;
public class WebHttpHandlerBuilderTests { public class WebHttpHandlerBuilderTests {
@Test // SPR-15074 @Test // SPR-15074
public void orderedWebFilterBeans() throws Exception { public void orderedWebFilterBeans() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(OrderedWebFilterBeanConfig.class); context.register(OrderedWebFilterBeanConfig.class);
context.refresh(); context.refresh();
HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(context).build(); HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(context).build();
assertTrue(httpHandler instanceof HttpWebHandlerAdapter); assertTrue(httpHandler instanceof HttpWebHandlerAdapter);
assertSame(context, ((HttpWebHandlerAdapter) httpHandler).getApplicationContext()); assertSame(context, ((HttpWebHandlerAdapter) httpHandler).getApplicationContext());
@ -66,13 +63,12 @@ public class WebHttpHandlerBuilderTests {
} }
@Test // SPR-15074 @Test // SPR-15074
public void orderedWebExceptionHandlerBeans() throws Exception { public void orderedWebExceptionHandlerBeans() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(OrderedExceptionHandlerBeanConfig.class); context.register(OrderedExceptionHandlerBeanConfig.class);
context.refresh(); context.refresh();
HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(context).build(); HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(context).build();
MockServerHttpRequest request = MockServerHttpRequest.get("/").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/").build();
MockServerHttpResponse response = new MockServerHttpResponse(); MockServerHttpResponse response = new MockServerHttpResponse();
httpHandler.handle(request, response).block(ofMillis(5000)); httpHandler.handle(request, response).block(ofMillis(5000));
@ -81,13 +77,12 @@ public class WebHttpHandlerBuilderTests {
} }
@Test @Test
public void configWithoutFilters() throws Exception { public void configWithoutFilters() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(NoFilterConfig.class); context.register(NoFilterConfig.class);
context.refresh(); context.refresh();
HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(context).build(); HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(context).build();
MockServerHttpRequest request = MockServerHttpRequest.get("/").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/").build();
MockServerHttpResponse response = new MockServerHttpResponse(); MockServerHttpResponse response = new MockServerHttpResponse();
httpHandler.handle(request, response).block(ofMillis(5000)); httpHandler.handle(request, response).block(ofMillis(5000));
@ -95,6 +90,17 @@ public class WebHttpHandlerBuilderTests {
assertEquals("handled", response.getBodyAsString().block(ofMillis(5000))); assertEquals("handled", response.getBodyAsString().block(ofMillis(5000)));
} }
@Test // SPR-16972
public void cloneWithApplicationContext() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(NoFilterConfig.class);
context.refresh();
WebHttpHandlerBuilder builder = WebHttpHandlerBuilder.applicationContext(context);
assertSame(context, ((HttpWebHandlerAdapter) builder.build()).getApplicationContext());
assertSame(context, ((HttpWebHandlerAdapter) builder.clone().build()).getApplicationContext());
}
private static Mono<Void> writeToResponse(ServerWebExchange exchange, String value) { private static Mono<Void> writeToResponse(ServerWebExchange exchange, String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8); byte[] bytes = value.getBytes(StandardCharsets.UTF_8);