Defer javax.servlet.Filter initialization

Update `DelegatingFilterProxyRegistrationBean` so that calls to the
`init()` method no longer trigger early bean initialization.

See gh-6178
This commit is contained in:
Phillip Webb 2016-06-29 20:13:58 -07:00
parent be884d4e33
commit 4d50b4d321
2 changed files with 51 additions and 3 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.boot.web.servlet;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -84,7 +85,15 @@ public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistr
@Override @Override
public Filter getFilter() { public Filter getFilter() {
return new DelegatingFilterProxy(this.targetBeanName, getWebApplicationContext()); return new DelegatingFilterProxy(this.targetBeanName,
getWebApplicationContext()) {
@Override
protected void initFilterBean() throws ServletException {
// Don't initialize filter bean on init()
}
};
} }
private WebApplicationContext getWebApplicationContext() { private WebApplicationContext getWebApplicationContext() {

View File

@ -16,15 +16,26 @@
package org.springframework.boot.web.servlet; package org.springframework.boot.web.servlet;
import java.io.IOException;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext; import org.springframework.mock.web.MockServletContext;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.filter.GenericFilterBean;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.isA; import static org.mockito.Matchers.isA;
@ -37,7 +48,9 @@ import static org.mockito.Matchers.isA;
public class DelegatingFilterProxyRegistrationBeanTests public class DelegatingFilterProxyRegistrationBeanTests
extends AbstractFilterRegistrationBeanTests { extends AbstractFilterRegistrationBeanTests {
private WebApplicationContext applicationContext = new GenericWebApplicationContext( private static ThreadLocal<Boolean> mockFilterInitialized = new ThreadLocal<Boolean>();
private GenericWebApplicationContext applicationContext = new GenericWebApplicationContext(
new MockServletContext()); new MockServletContext());
@Test @Test
@ -71,6 +84,19 @@ public class DelegatingFilterProxyRegistrationBeanTests
.isEqualTo("mockFilter"); .isEqualTo("mockFilter");
} }
@Test
public void initShouldNotCauseEarlyInitialization() throws Exception {
this.applicationContext.registerBeanDefinition("mockFilter",
new RootBeanDefinition(MockFilter.class));
AbstractFilterRegistrationBean registrationBean = createFilterRegistrationBean();
Filter filter = registrationBean.getFilter();
filter.init(new MockFilterConfig());
assertThat(mockFilterInitialized.get()).isNull();
filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(),
new MockFilterChain());
assertThat(mockFilterInitialized.get()).isEqualTo(true);
}
@Test @Test
public void createServletRegistrationBeanMustNotBeNull() throws Exception { public void createServletRegistrationBeanMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class); this.thrown.expect(IllegalArgumentException.class);
@ -93,4 +119,17 @@ public class DelegatingFilterProxyRegistrationBeanTests
return isA(DelegatingFilterProxy.class); return isA(DelegatingFilterProxy.class);
} }
static class MockFilter extends GenericFilterBean {
MockFilter() {
mockFilterInitialized.set(true);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
}
}
} }