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(
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue