diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java index 78f7bd2ecd..5d7cb49cb5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java @@ -25,11 +25,14 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; +import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; +import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.context.annotation.Bean; @@ -45,6 +48,7 @@ import org.springframework.http.client.reactive.ReactorResourceFactory; * * @author Brian Clozel * @author Raheela Aslam + * @author Sergey Serdyuk */ abstract class ReactiveWebServerFactoryConfiguration { @@ -105,8 +109,11 @@ abstract class ReactiveWebServerFactoryConfiguration { @Bean public JettyReactiveWebServerFactory jettyReactiveWebServerFactory( - JettyResourceFactory resourceFactory) { + JettyResourceFactory resourceFactory, + ObjectProvider serverCustomizers) { JettyReactiveWebServerFactory serverFactory = new JettyReactiveWebServerFactory(); + serverFactory.getServerCustomizers().addAll( + serverCustomizers.orderedStream().collect(Collectors.toList())); serverFactory.setResourceFactory(resourceFactory); return serverFactory; } @@ -119,8 +126,15 @@ abstract class ReactiveWebServerFactoryConfiguration { static class EmbeddedUndertow { @Bean - public UndertowReactiveWebServerFactory undertowReactiveWebServerFactory() { - return new UndertowReactiveWebServerFactory(); + public UndertowReactiveWebServerFactory undertowReactiveWebServerFactory( + ObjectProvider deploymentInfoCustomizers, + ObjectProvider builderCustomizers) { + UndertowReactiveWebServerFactory factory = new UndertowReactiveWebServerFactory(); + factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers + .orderedStream().collect(Collectors.toList())); + factory.getBuilderCustomizers().addAll( + builderCustomizers.orderedStream().collect(Collectors.toList())); + return factory; } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java index fceccda369..d5f294775e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java @@ -32,11 +32,14 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; @@ -54,6 +57,7 @@ import org.springframework.context.annotation.Configuration; * @author Brian Clozel * @author Stephane Nicoll * @author Raheela Asalm + * @author Sergey Serdyuk */ @Configuration(proxyBeanMethods = false) class ServletWebServerFactoryConfiguration { @@ -93,8 +97,12 @@ class ServletWebServerFactoryConfiguration { public static class EmbeddedJetty { @Bean - public JettyServletWebServerFactory JettyServletWebServerFactory() { - return new JettyServletWebServerFactory(); + public JettyServletWebServerFactory JettyServletWebServerFactory( + ObjectProvider serverCustomizers) { + JettyServletWebServerFactory factory = new JettyServletWebServerFactory(); + factory.getServerCustomizers().addAll( + serverCustomizers.orderedStream().collect(Collectors.toList())); + return factory; } } @@ -109,8 +117,15 @@ class ServletWebServerFactoryConfiguration { public static class EmbeddedUndertow { @Bean - public UndertowServletWebServerFactory undertowServletWebServerFactory() { - return new UndertowServletWebServerFactory(); + public UndertowServletWebServerFactory undertowServletWebServerFactory( + ObjectProvider deploymentInfoCustomizers, + ObjectProvider builderCustomizers) { + UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(); + factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers + .orderedStream().collect(Collectors.toList())); + factory.getBuilderCustomizers().addAll( + builderCustomizers.orderedStream().collect(Collectors.toList())); + return factory; } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java index f3efd04152..849abfc91c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java @@ -20,16 +20,26 @@ import org.junit.Test; import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; +import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; +import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; +import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory; +import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext; import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ApplicationContextException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -149,6 +159,48 @@ public class ReactiveWebServerFactoryAutoConfigurationTests { }); } + @Test + public void jettyServerCustomizerBeanIsAddedToFactory() { + ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( + AnnotationConfigReactiveWebApplicationContext::new) + .withConfiguration(AutoConfigurations + .of(ReactiveWebServerFactoryAutoConfiguration.class)) + .withUserConfiguration(JettyServerCustomizer.class); + runner.run((context) -> { + JettyReactiveWebServerFactory factory = context + .getBean(JettyReactiveWebServerFactory.class); + assertThat(factory.getServerCustomizers()).hasSize(1); + }); + } + + @Test + public void undertowDeploymentInfoCustomizerBeanIsAddedToFactory() { + ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( + AnnotationConfigReactiveWebApplicationContext::new) + .withConfiguration(AutoConfigurations + .of(ReactiveWebServerFactoryAutoConfiguration.class)) + .withUserConfiguration(UndertowDeploymentInfoCustomizer.class); + runner.run((context) -> { + UndertowReactiveWebServerFactory factory = context + .getBean(UndertowReactiveWebServerFactory.class); + assertThat(factory.getDeploymentInfoCustomizers()).hasSize(1); + }); + } + + @Test + public void undertowBuilderCustomizerBeanIsAddedToFactory() { + ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( + AnnotationConfigReactiveWebApplicationContext::new) + .withConfiguration(AutoConfigurations + .of(ReactiveWebServerFactoryAutoConfiguration.class)) + .withUserConfiguration(UndertowBuilderCustomizer.class); + runner.run((context) -> { + UndertowReactiveWebServerFactory factory = context + .getBean(UndertowReactiveWebServerFactory.class); + assertThat(factory.getBuilderCustomizers()).hasSize(1); + }); + } + @Test public void forwardedHeaderTransformerShouldBeConfigured() { this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java index 6c62abb5f4..87bc2131bf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java @@ -31,10 +31,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; +import org.springframework.boot.web.embedded.undertow.UndertowServletWebServer; +import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; @@ -147,6 +153,48 @@ public class ServletWebServerFactoryAutoConfigurationTests { }); } + @Test + public void jettyServerCustomizerBeanIsAddedToFactory() { + WebApplicationContextRunner runner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations + .of(ServletWebServerFactoryAutoConfiguration.class)) + .withUserConfiguration(JettyServerCustomizer.class); + runner.run((context) -> { + JettyServletWebServerFactory factory = context + .getBean(JettyServletWebServerFactory.class); + assertThat(factory.getServerCustomizers()).hasSize(1); + }); + } + + @Test + public void undertowDeploymentInfoCustomizerBeanIsAddedToFactory() { + WebApplicationContextRunner runner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations + .of(ServletWebServerFactoryAutoConfiguration.class)) + .withUserConfiguration(UndertowDeploymentInfoCustomizer.class); + runner.run((context) -> { + UndertowServletWebServerFactory factory = context + .getBean(UndertowServletWebServerFactory.class); + assertThat(factory.getDeploymentInfoCustomizers()).hasSize(1); + }); + } + + @Test + public void undertowBuilderCustomizerBeanIsAddedToFactory() { + WebApplicationContextRunner runner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations + .of(ServletWebServerFactoryAutoConfiguration.class)) + .withUserConfiguration(UndertowBuilderCustomizer.class); + runner.run((context) -> { + UndertowServletWebServerFactory factory = context + .getBean(UndertowServletWebServerFactory.class); + assertThat(factory.getBuilderCustomizers()).hasSize(1); + }); + } + @Test public void tomcatConnectorCustomizerBeanIsAddedToFactory() { WebApplicationContextRunner runner = new WebApplicationContextRunner(