From 659d7b6df1e9d2f744b8ec51b2c0be65825ac07b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 13 Mar 2014 09:33:29 +0000 Subject: [PATCH] Extend DefaultDispatcherServletCondition to check for a registration ...bean with no explicit @Bean DispatcherServlet. We still have to check by bean name (slightly unfortunate, but we need to avoid instantiating too early) so there's now another magic bean name for the registration bean ("dispatcherServletRegistration") that the user has to replace if he wants the registration without defining a servlet @Bean Fixes gh-482 --- .../DispatcherServletAutoConfiguration.java | 56 ++++++++++++++++++- ...spatcherServletAutoConfigurationTests.java | 26 +++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration.java index 52ef8d65ad..7dff563257 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration.java @@ -62,6 +62,11 @@ public class DispatcherServletAutoConfiguration { */ public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet"; + /* + * The bean name for a ServletRegistrationBean for the DispatcherServlet "/" + */ + public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration"; + @Configuration @Conditional(DefaultDispatcherServletCondition.class) @ConditionalOnClass(ServletRegistration.class) @@ -78,10 +83,11 @@ public class DispatcherServletAutoConfiguration { return new DispatcherServlet(); } - @Bean + @Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME) public ServletRegistrationBean dispatcherServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean( dispatcherServlet(), this.server.getServletPath()); + registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); if (this.multipartConfig != null) { registration.setMultipartConfig(this.multipartConfig); } @@ -97,6 +103,17 @@ public class DispatcherServletAutoConfiguration { AnnotatedTypeMetadata metadata) { ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); + + ConditionOutcome outcome = checkServlets(beanFactory); + + if (!outcome.isMatch()) { + return outcome; + } + + return checkServletRegistrations(beanFactory); + } + + private ConditionOutcome checkServlets(ConfigurableListableBeanFactory beanFactory) { List servlets = Arrays.asList(beanFactory.getBeanNamesForType( DispatcherServlet.class, false, false)); boolean containsDispatcherBean = beanFactory @@ -117,9 +134,46 @@ public class DispatcherServletAutoConfiguration { return ConditionOutcome.noMatch("found non-DispatcherServlet named " + DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); } + return ConditionOutcome .match("one or more DispatcherServlets found and none is named " + DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); + + } + + /** + */ + protected ConditionOutcome checkServletRegistrations( + ConfigurableListableBeanFactory beanFactory) { + + List registrations = Arrays.asList(beanFactory.getBeanNamesForType( + ServletRegistrationBean.class, false, false)); + boolean containsDispatcherRegistrationBean = beanFactory + .containsBean(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME); + + if (registrations.isEmpty()) { + if (containsDispatcherRegistrationBean) { + return ConditionOutcome + .noMatch("found no ServletRegistrationBean but a non-ServletRegistrationBean named " + + DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME); + } + return ConditionOutcome.match("no ServletRegistrationBean found"); + } + + if (registrations.contains(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)) { + return ConditionOutcome.noMatch("found ServletRegistrationBean named " + + DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME); + } + if (containsDispatcherRegistrationBean) { + return ConditionOutcome + .noMatch("found non-ServletRegistrationBean named " + + DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME); + } + + return ConditionOutcome + .match("one or more ServletRegistrationBeans is found and none is named " + + DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME); + } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfigurationTests.java index 6f54501f6e..15c6f20cda 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfigurationTests.java @@ -54,6 +54,21 @@ public class DispatcherServletAutoConfigurationTests { assertEquals("[/]", registration.getUrlMappings().toString()); } + @Test + public void registrationOverride() throws Exception { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.register(CustomDispatcherRegistration.class, + ServerPropertiesAutoConfiguration.class, + DispatcherServletAutoConfiguration.class); + this.context.setServletContext(new MockServletContext()); + this.context.refresh(); + ServletRegistrationBean registration = this.context + .getBean(ServletRegistrationBean.class); + assertEquals("[/foo]", registration.getUrlMappings().toString()); + assertEquals("customDispatcher", registration.getServletName()); + assertEquals(0, this.context.getBeanNamesForType(DispatcherServlet.class).length); + } + @Test public void servletPath() throws Exception { this.context = new AnnotationConfigWebApplicationContext(); @@ -95,4 +110,15 @@ public class DispatcherServletAutoConfigurationTests { } + @Configuration + protected static class CustomDispatcherRegistration { + @Bean + public ServletRegistrationBean dispatcherServletRegistration() { + ServletRegistrationBean registration = new ServletRegistrationBean( + new DispatcherServlet(), "/foo"); + registration.setName("customDispatcher"); + return registration; + } + } + }