diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java index 0e0456618ed..a18304855e1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java @@ -55,6 +55,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.ServletContextAwareProcessor; import org.springframework.web.context.support.ServletContextResource; +import org.springframework.web.context.support.ServletContextScope; import org.springframework.web.context.support.WebApplicationContextUtils; /** @@ -132,7 +133,7 @@ public class ServletWebServerApplicationContext extends GenericWebApplicationCon beanFactory.addBeanPostProcessor( new WebApplicationContextServletContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); - registerWebApplicationScopes(null); + registerWebApplicationScopes(); } @Override @@ -227,7 +228,7 @@ public class ServletWebServerApplicationContext extends GenericWebApplicationCon private void selfInitialize(ServletContext servletContext) throws ServletException { prepareWebApplicationContext(servletContext); - registerWebApplicationScopes(servletContext); + registerApplicationScope(servletContext); WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext); for (ServletContextInitializer beans : getServletContextInitializerBeans()) { @@ -235,11 +236,17 @@ public class ServletWebServerApplicationContext extends GenericWebApplicationCon } } - private void registerWebApplicationScopes(ServletContext servletContext) { + private void registerApplicationScope(ServletContext servletContext) { + ServletContextScope appScope = new ServletContextScope(servletContext); + getBeanFactory().registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); + // Register as ServletContext attribute, for ContextCleanupListener to detect it. + servletContext.setAttribute(ServletContextScope.class.getName(), appScope); + } + + private void registerWebApplicationScopes() { ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes( getBeanFactory()); - WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory(), - servletContext); + WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory()); existingScopes.restore(); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextTests.java index 237d1874836..db7a0d9e7f0 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextTests.java @@ -47,6 +47,7 @@ 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.testsupport.rule.OutputCapture; import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -91,6 +92,9 @@ public class ServletWebServerApplicationContextTests { private ServletWebServerApplicationContext context; + @Rule + public OutputCapture output = new OutputCapture(); + @Captor private ArgumentCaptor filterCaptor; @@ -463,6 +467,7 @@ public class ServletWebServerApplicationContextTests { @Test public void servletRequestCanBeInjectedEarly() throws Exception { // gh-14990 + int initialOutputLength = this.output.toString().length(); addWebServerFactoryBean(); RootBeanDefinition beanDefinition = new RootBeanDefinition( WithAutowiredServletRequest.class); @@ -481,6 +486,16 @@ public class ServletWebServerApplicationContextTests { }); this.context.refresh(); + String output = this.output.toString().substring(initialOutputLength); + assertThat(output).doesNotContain("Replacing scope"); + } + + @Test + public void webApplicationScopeIsRegistered() throws Exception { + addWebServerFactoryBean(); + this.context.refresh(); + assertThat(this.context.getBeanFactory() + .getRegisteredScope(WebApplicationContext.SCOPE_APPLICATION)).isNotNull(); } private void addWebServerFactoryBean() { @@ -549,4 +564,18 @@ public class ServletWebServerApplicationContextTests { } + protected static class WithAutowiredServletContext { + + private final ServletContext context; + + public WithAutowiredServletContext(ServletContext context) { + this.context = context; + } + + public ServletContext getContext() { + return this.context; + } + + } + }