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 436f3fc60eb..1611428d824 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 @@ -114,6 +114,7 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext beanFactory.addBeanPostProcessor( new WebApplicationContextServletContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); + registerWebApplicationScopes(null); } @Override @@ -217,19 +218,22 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext private void selfInitialize(ServletContext servletContext) throws ServletException { prepareEmbeddedWebApplicationContext(servletContext); - ConfigurableListableBeanFactory beanFactory = getBeanFactory(); - ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes( - beanFactory); - WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, - getServletContext()); - existingScopes.restore(); - WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, - getServletContext()); + registerWebApplicationScopes(servletContext); + WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), + servletContext); for (ServletContextInitializer beans : getServletContextInitializerBeans()) { beans.onStartup(servletContext); } } + private void registerWebApplicationScopes(ServletContext servletContext) { + ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes( + getBeanFactory()); + WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory(), + servletContext); + existingScopes.restore(); + } + /** * Returns {@link ServletContextInitializer}s that should be used with the embedded * Servlet context. By default this method will first attempt to find 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 b40475407bd..5fa0bc259fb 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 @@ -41,12 +41,15 @@ import org.mockito.Captor; import org.mockito.InOrder; import org.mockito.MockitoAnnotations; +import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.Scope; +import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -466,7 +469,8 @@ public class EmbeddedWebApplicationContextTests { } @Test - public void doesNotReplaceExistingScopes() throws Exception { // gh-2082 + public void doesNotReplaceExistingScopes() throws Exception { + // gh-2082 Scope scope = mock(Scope.class); ConfigurableListableBeanFactory factory = this.context.getBeanFactory(); factory.registerScope(WebApplicationContext.SCOPE_REQUEST, scope); @@ -482,6 +486,29 @@ public class EmbeddedWebApplicationContextTests { .isSameAs(scope); } + @Test + public void servletRequestCanBeInjectedEarly() throws Exception { + // gh-14990 + addEmbeddedServletContainerFactoryBean(); + RootBeanDefinition beanDefinition = new RootBeanDefinition( + WithAutowiredServletRequest.class); + beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR); + this.context.registerBeanDefinition("withAutowiredServletRequest", + beanDefinition); + this.context.addBeanFactoryPostProcessor(new BeanFactoryPostProcessor() { + + @Override + public void postProcessBeanFactory( + ConfigurableListableBeanFactory beanFactory) throws BeansException { + WithAutowiredServletRequest bean = beanFactory + .getBean(WithAutowiredServletRequest.class); + assertThat(bean.getRequest()).isNotNull(); + } + + }); + this.context.refresh(); + } + private void addEmbeddedServletContainerFactoryBean() { this.context.registerBeanDefinition("embeddedServletContainerFactory", new RootBeanDefinition(MockEmbeddedServletContainerFactory.class)); @@ -534,4 +561,18 @@ public class EmbeddedWebApplicationContextTests { } + protected static class WithAutowiredServletRequest { + + private final ServletRequest request; + + public WithAutowiredServletRequest(ServletRequest request) { + this.request = request; + } + + public ServletRequest getRequest() { + return this.request; + } + + } + }