From d1dcb015b67e0f80a0bbb8c32f4867cdd1d5137d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 27 Nov 2013 15:03:58 +0000 Subject: [PATCH] Ensure only supported listeners are instantiated Previously all EventListeners were eagerly instantiated but that can cause problems because it happens quite early in the lifecycle. Better to be explicit about the supported types. --- .../web/WebMvcAutoConfiguration.java | 7 +++++++ .../EmbeddedWebApplicationContext.java | 21 +++++++++++-------- .../ServletListenerRegistrationBean.java | 7 +++++++ .../EmbeddedWebApplicationContextTests.java | 13 ++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index 02ca19122e..622b2722d4 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -47,6 +47,7 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistry; import org.springframework.web.accept.ContentNegotiationManager; +import org.springframework.web.context.request.RequestContextListener; import org.springframework.web.filter.HiddenHttpMethodFilter; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.View; @@ -134,6 +135,12 @@ public class WebMvcAutoConfiguration { return resolver; } + @Bean + @ConditionalOnMissingBean(RequestContextListener.class) + public RequestContextListener requestContextListener() { + return new RequestContextListener(); + } + @Bean @ConditionalOnBean(View.class) public BeanNameViewResolver beanNameViewResolver() { diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContext.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContext.java index b0492b2b99..eb6130cad6 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContext.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContext.java @@ -276,15 +276,18 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext } } - for (Entry listenerBean : getOrderedBeansOfType(EventListener.class)) { - String name = listenerBean.getKey(); - EventListener listener = listenerBean.getValue(); - if (ServletListenerRegistrationBean.isSupportedType(listener) - && !filterRegistrations.contains(listener)) { - ServletListenerRegistrationBean registration = new ServletListenerRegistrationBean( - listener); - registration.setName(name); - initializers.add(registration); + Set> listenerTypes = ServletListenerRegistrationBean.getSupportedTypes(); + for (Class type : listenerTypes) { + for (Entry listenerBean : getOrderedBeansOfType(type)) { + String name = listenerBean.getKey(); + EventListener listener = (EventListener) listenerBean.getValue(); + if (ServletListenerRegistrationBean.isSupportedType(listener) + && !filterRegistrations.contains(listener)) { + ServletListenerRegistrationBean registration = new ServletListenerRegistrationBean( + listener); + registration.setName(name); + initializers.add(registration); + } } } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/ServletListenerRegistrationBean.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/ServletListenerRegistrationBean.java index 36442e7edf..bababae8b7 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/ServletListenerRegistrationBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/ServletListenerRegistrationBean.java @@ -118,4 +118,11 @@ public class ServletListenerRegistrationBean extends return false; } + /** + * @return the supportedTypes for this registration + */ + public static Set> getSupportedTypes() { + return SUPPORTED_TYPES; + } + } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContextTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContextTests.java index d7c61f696b..c193062bc3 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContextTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContextTests.java @@ -22,6 +22,7 @@ import java.util.Properties; import javax.servlet.Filter; import javax.servlet.Servlet; import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; import org.junit.After; import org.junit.Before; @@ -264,6 +265,18 @@ public class EmbeddedWebApplicationContextTests { ordered.verify(initializer2).onStartup(servletContext); } + @Test + public void servletContextListenerBeans() throws Exception { + addEmbeddedServletContainerFactoryBean(); + ServletContextListener initializer = mock(ServletContextListener.class); + this.context.registerBeanDefinition("initializerBean", + beanDefinition(initializer)); + this.context.refresh(); + ServletContext servletContext = getEmbeddedServletContainerFactory() + .getServletContext(); + verify(servletContext).addListener(initializer); + } + @Test public void unorderedServletContextInitializerBeans() throws Exception { addEmbeddedServletContainerFactoryBean();