diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java index 9bd859b7ebc..86995cb0be9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -65,10 +65,18 @@ class DispatcherServletAutoConfigurationTests { }); } - // If a DispatcherServlet instance is registered with a name different - // from the default one, we're registering one anyway @Test - void registrationOverrideWithDispatcherServletWrongName() { + void registrationOverrideWithDefaultDispatcherServletNameResultsInSingleDispatcherServlet() { + this.contextRunner.withUserConfiguration(CustomDispatcherServletSameName.class).run((context) -> { + ServletRegistrationBean registration = context.getBean(ServletRegistrationBean.class); + assertThat(registration.getUrlMappings()).containsExactly("/"); + assertThat(registration.getServletName()).isEqualTo("dispatcherServlet"); + assertThat(context).getBeanNames(DispatcherServlet.class).hasSize(1); + }); + } + + @Test + void registrationOverrideWithNonDefaultDispatcherServletNameResultsInTwoDispatcherServlets() { this.contextRunner .withUserConfiguration(CustomDispatcherServletDifferentName.class, CustomDispatcherServletPath.class) .run((context) -> { 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 a3211bd3417..689b15bcaf0 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 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,10 +19,7 @@ package org.springframework.boot.autoconfigure.web.servlet; import io.undertow.Undertow.Builder; import io.undertow.servlet.api.DeploymentInfo; import jakarta.servlet.Filter; -import jakarta.servlet.Servlet; import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.catalina.startup.Tomcat; @@ -34,10 +31,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.test.context.FilteredClassLoader; -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.testsupport.web.servlet.DirtiesUrlFactories; import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; @@ -49,19 +43,15 @@ import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCust 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; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import org.springframework.web.filter.ForwardedHeaderFilter; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.FrameworkServlet; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -77,69 +67,31 @@ import static org.mockito.Mockito.mock; * @author Raheela Aslam * @author Madhura Bhave */ -@DirtiesUrlFactories class ServletWebServerFactoryAutoConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class, - DispatcherServletAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) .withUserConfiguration(WebServerConfiguration.class); @Test void createFromConfigClass() { - this.contextRunner.run(verifyContext()); - } - - @Test - void contextAlreadyHasDispatcherServletWithDefaultName() { - this.contextRunner.withUserConfiguration(DispatcherServletConfiguration.class).run(verifyContext()); - } - - @Test - void contextAlreadyHasDispatcherServlet() { - this.contextRunner.withUserConfiguration(SpringServletConfiguration.class).run((context) -> { - verifyContext(context); - assertThat(context.getBeanNamesForType(DispatcherServlet.class)).hasSize(2); - }); - } - - @Test - void contextAlreadyHasNonDispatcherServlet() { - this.contextRunner.withUserConfiguration(NonSpringServletConfiguration.class).run((context) -> { - verifyContext(context); // the non default servlet is still registered - assertThat(context).doesNotHaveBean(DispatcherServlet.class); - }); - } - - @Test - void contextAlreadyHasNonServlet() { - this.contextRunner.withUserConfiguration(NonServletConfiguration.class).run((context) -> { - assertThat(context).doesNotHaveBean(DispatcherServlet.class); - assertThat(context).doesNotHaveBean(Servlet.class); - }); - } - - @Test - void contextAlreadyHasDispatcherServletAndRegistration() { - this.contextRunner.withUserConfiguration(DispatcherServletWithRegistrationConfiguration.class) - .run((context) -> { - verifyContext(context); - assertThat(context).hasSingleBean(DispatcherServlet.class); - }); + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ServletWebServerFactoryCustomizer.class)); } @Test void webServerHasNoServletContext() { - this.contextRunner.withUserConfiguration(EnsureWebServerHasNoServletContext.class).run(verifyContext()); + this.contextRunner.withUserConfiguration(EnsureWebServerHasNoServletContext.class) + .run((context) -> assertThat(context).hasNotFailed()); } @Test - void customizeWebServerFactoryThroughCallback() { - this.contextRunner.withUserConfiguration(CallbackEmbeddedServerFactoryCustomizer.class).run((context) -> { - verifyContext(context); - assertThat(context.getBean(MockServletWebServerFactory.class).getPort()).isEqualTo(9000); - }); + void webServerFactoryCustomizerBeansAreCalledToCustomizeWebServerFactory() { + this.contextRunner + .withBean(WebServerFactoryCustomizer.class, + () -> (WebServerFactoryCustomizer) (factory) -> factory + .setPort(9000)) + .run((context) -> assertThat(context.getBean(MockServletWebServerFactory.class).getPort()).isEqualTo(9000)); } @Test @@ -424,17 +376,6 @@ class ServletWebServerFactoryAutoConfigurationTests { }); } - private ContextConsumer verifyContext() { - return this::verifyContext; - } - - private void verifyContext(ApplicationContext context) { - MockServletWebServerFactory factory = context.getBean(MockServletWebServerFactory.class); - Servlet servlet = context.getBean(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME, - Servlet.class); - then(factory.getServletContext()).should().addServlet("dispatcherServlet", servlet); - } - @Configuration(proxyBeanMethods = false) @ConditionalOnExpression("true") static class WebServerConfiguration { @@ -446,68 +387,6 @@ class ServletWebServerFactoryAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - static class DispatcherServletConfiguration { - - @Bean - DispatcherServlet dispatcherServlet() { - return new DispatcherServlet(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class SpringServletConfiguration { - - @Bean - DispatcherServlet springServlet() { - return new DispatcherServlet(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class NonSpringServletConfiguration { - - @Bean - FrameworkServlet dispatcherServlet() { - return new FrameworkServlet() { - @Override - protected void doService(HttpServletRequest request, HttpServletResponse response) { - } - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class NonServletConfiguration { - - @Bean - String dispatcherServlet() { - return "foo"; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DispatcherServletWithRegistrationConfiguration { - - @Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) - DispatcherServlet dispatcherServlet() { - return new DispatcherServlet(); - } - - @Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME) - ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) { - ServletRegistrationBean registration = new ServletRegistrationBean<>(dispatcherServlet, - "/app/*"); - registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); - return registration; - } - - } - @Component static class EnsureWebServerHasNoServletContext implements BeanPostProcessor { @@ -527,17 +406,6 @@ class ServletWebServerFactoryAutoConfigurationTests { } - @Component - static class CallbackEmbeddedServerFactoryCustomizer - implements WebServerFactoryCustomizer { - - @Override - public void customize(ConfigurableServletWebServerFactory serverFactory) { - serverFactory.setPort(9000); - } - - } - @Configuration(proxyBeanMethods = false) static class TomcatConnectorCustomizerConfiguration {