Allow early ServletRequest Autowiring
Update `EmbeddedWebApplicationContext` so that Servlet related resolvable dependencies are registered in `postProcessBeanFactory`. This allows a `ServletReqest` to be autowired into an early initialized bean and brings parity with WAR based deployments. Closes gh-14990
This commit is contained in:
parent
fb85d0acc1
commit
b60da5f85d
|
@ -114,6 +114,7 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
|
||||||
beanFactory.addBeanPostProcessor(
|
beanFactory.addBeanPostProcessor(
|
||||||
new WebApplicationContextServletContextAwareProcessor(this));
|
new WebApplicationContextServletContextAwareProcessor(this));
|
||||||
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
|
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
|
||||||
|
registerWebApplicationScopes(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -217,19 +218,22 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
|
||||||
|
|
||||||
private void selfInitialize(ServletContext servletContext) throws ServletException {
|
private void selfInitialize(ServletContext servletContext) throws ServletException {
|
||||||
prepareEmbeddedWebApplicationContext(servletContext);
|
prepareEmbeddedWebApplicationContext(servletContext);
|
||||||
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
|
registerWebApplicationScopes(servletContext);
|
||||||
ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(
|
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(),
|
||||||
beanFactory);
|
servletContext);
|
||||||
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory,
|
|
||||||
getServletContext());
|
|
||||||
existingScopes.restore();
|
|
||||||
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory,
|
|
||||||
getServletContext());
|
|
||||||
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
|
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
|
||||||
beans.onStartup(servletContext);
|
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
|
* Returns {@link ServletContextInitializer}s that should be used with the embedded
|
||||||
* Servlet context. By default this method will first attempt to find
|
* Servlet context. By default this method will first attempt to find
|
||||||
|
|
|
@ -41,12 +41,15 @@ import org.mockito.Captor;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
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.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||||
import org.springframework.beans.factory.config.Scope;
|
import org.springframework.beans.factory.config.Scope;
|
||||||
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
|
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
@ -466,7 +469,8 @@ public class EmbeddedWebApplicationContextTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doesNotReplaceExistingScopes() throws Exception { // gh-2082
|
public void doesNotReplaceExistingScopes() throws Exception {
|
||||||
|
// gh-2082
|
||||||
Scope scope = mock(Scope.class);
|
Scope scope = mock(Scope.class);
|
||||||
ConfigurableListableBeanFactory factory = this.context.getBeanFactory();
|
ConfigurableListableBeanFactory factory = this.context.getBeanFactory();
|
||||||
factory.registerScope(WebApplicationContext.SCOPE_REQUEST, scope);
|
factory.registerScope(WebApplicationContext.SCOPE_REQUEST, scope);
|
||||||
|
@ -482,6 +486,29 @@ public class EmbeddedWebApplicationContextTests {
|
||||||
.isSameAs(scope);
|
.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() {
|
private void addEmbeddedServletContainerFactoryBean() {
|
||||||
this.context.registerBeanDefinition("embeddedServletContainerFactory",
|
this.context.registerBeanDefinition("embeddedServletContainerFactory",
|
||||||
new RootBeanDefinition(MockEmbeddedServletContainerFactory.class));
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue