Skip to content

Commit a1491be

Browse files
committed
Refine DispatcherServletPathProvider creation
Closes gh-13527
1 parent 0411958 commit a1491be

File tree

2 files changed

+89
-9
lines changed

2 files changed

+89
-9
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3434
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3535
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
36+
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
3637
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
3738
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
3839
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
@@ -116,12 +117,6 @@ public MultipartResolver multipartResolver(MultipartResolver resolver) {
116117
return resolver;
117118
}
118119

119-
@Bean
120-
public DispatcherServletPathProvider mainDispatcherServletPathProvider() {
121-
return () -> DispatcherServletConfiguration.this.serverProperties.getServlet()
122-
.getPath();
123-
}
124-
125120
}
126121

127122
@Configuration
@@ -161,6 +156,14 @@ public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration(
161156
return registration;
162157
}
163158

159+
@Bean
160+
@ConditionalOnMissingBean(DispatcherServletPathProvider.class)
161+
@ConditionalOnSingleCandidate(DispatcherServlet.class)
162+
public DispatcherServletPathProvider dispatcherServletPathProvider() {
163+
return () -> DispatcherServletRegistrationConfiguration.this.serverProperties
164+
.getServlet().getPath();
165+
}
166+
164167
}
165168

166169
@Order(Ordered.LOWEST_PRECEDENCE - 10)

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.springframework.web.servlet.DispatcherServlet;
3636

3737
import static org.assertj.core.api.Assertions.assertThat;
38+
import static org.mockito.Mockito.mock;
3839

3940
/**
4041
* Tests for {@link DispatcherServletAutoConfiguration}.
@@ -65,6 +66,8 @@ public void registrationNonServletBean() {
6566
.run((context) -> {
6667
assertThat(context).doesNotHaveBean(ServletRegistrationBean.class);
6768
assertThat(context).doesNotHaveBean(DispatcherServlet.class);
69+
assertThat(context)
70+
.doesNotHaveBean(DispatcherServletPathProvider.class);
6871
});
6972
}
7073

@@ -73,7 +76,8 @@ public void registrationNonServletBean() {
7376
@Test
7477
public void registrationOverrideWithDispatcherServletWrongName() {
7578
this.contextRunner
76-
.withUserConfiguration(CustomDispatcherServletDifferentName.class)
79+
.withUserConfiguration(CustomDispatcherServletDifferentName.class,
80+
CustomDispatcherServletPathProvider.class)
7781
.run((context) -> {
7882
ServletRegistrationBean<?> registration = context
7983
.getBean(ServletRegistrationBean.class);
@@ -86,8 +90,8 @@ public void registrationOverrideWithDispatcherServletWrongName() {
8690

8791
@Test
8892
public void registrationOverrideWithAutowiredServlet() {
89-
this.contextRunner.withUserConfiguration(CustomAutowiredRegistration.class)
90-
.run((context) -> {
93+
this.contextRunner.withUserConfiguration(CustomAutowiredRegistration.class,
94+
CustomDispatcherServletPathProvider.class).run((context) -> {
9195
ServletRegistrationBean<?> registration = context
9296
.getBean(ServletRegistrationBean.class);
9397
assertThat(registration.getUrlMappings()).containsExactly("/foo");
@@ -112,6 +116,40 @@ public void servletPath() {
112116
});
113117
}
114118

119+
@Test
120+
public void pathProviderNotCreatedWhenMultipleDispatcherServletsPresent() {
121+
this.contextRunner
122+
.withUserConfiguration(CustomDispatcherServletDifferentName.class)
123+
.run((context) -> assertThat(context)
124+
.doesNotHaveBean(DispatcherServletPathProvider.class));
125+
}
126+
127+
@Test
128+
public void pathProviderWhenCustomDispatcherServletSameNameShouldReturnConfiguredServletPath() {
129+
this.contextRunner.withUserConfiguration(CustomDispatcherServletSameName.class)
130+
.withPropertyValues("server.servlet.path:/spring")
131+
.run((context) -> assertThat(context
132+
.getBean(DispatcherServletPathProvider.class).getServletPath())
133+
.isEqualTo("/spring"));
134+
}
135+
136+
@Test
137+
public void pathProviderNotCreatedWhenDefaultDispatcherServletNotAvailable() {
138+
this.contextRunner
139+
.withUserConfiguration(CustomDispatcherServletDifferentName.class,
140+
NonServletConfiguration.class)
141+
.run((context) -> assertThat(context)
142+
.doesNotHaveBean(DispatcherServletPathProvider.class));
143+
}
144+
145+
@Test
146+
public void pathProviderNotCreatedWhenCustomRegistrationBeanPresent() {
147+
this.contextRunner
148+
.withUserConfiguration(CustomDispatcherServletRegistration.class)
149+
.run((context) -> assertThat(context)
150+
.doesNotHaveBean(DispatcherServletPathProvider.class));
151+
}
152+
115153
@Test
116154
public void multipartConfig() {
117155
this.contextRunner.withUserConfiguration(MultipartConfiguration.class)
@@ -198,6 +236,16 @@ public DispatcherServlet customDispatcherServlet() {
198236

199237
}
200238

239+
@Configuration
240+
protected static class CustomDispatcherServletPathProvider {
241+
242+
@Bean
243+
public DispatcherServletPathProvider dispatcherServletPathProvider() {
244+
return mock(DispatcherServletPathProvider.class);
245+
}
246+
247+
}
248+
201249
@Configuration
202250
protected static class CustomAutowiredRegistration {
203251

@@ -210,6 +258,11 @@ public ServletRegistrationBean<?> dispatcherServletRegistration(
210258
return registration;
211259
}
212260

261+
@Bean
262+
public DispatcherServletPathProvider dispatcherServletPathProvider() {
263+
return mock(DispatcherServletPathProvider.class);
264+
}
265+
213266
}
214267

215268
@Configuration
@@ -232,6 +285,30 @@ public MultipartResolver getMultipartResolver() {
232285

233286
}
234287

288+
@Configuration
289+
protected static class CustomDispatcherServletSameName {
290+
291+
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
292+
public DispatcherServlet dispatcherServlet() {
293+
return new DispatcherServlet();
294+
}
295+
296+
}
297+
298+
@Configuration
299+
protected static class CustomDispatcherServletRegistration {
300+
301+
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
302+
public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration(
303+
DispatcherServlet dispatcherServlet) {
304+
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(
305+
dispatcherServlet, "/foo");
306+
registration.setName("customDispatcher");
307+
return registration;
308+
}
309+
310+
}
311+
235312
private static class MockMultipartResolver implements MultipartResolver {
236313

237314
@Override

0 commit comments

Comments
 (0)