From 4d50b4d32150aa026eeb3d67bc240083f802f16c Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 29 Jun 2016 20:13:58 -0700 Subject: [PATCH] Defer javax.servlet.Filter initialization Update `DelegatingFilterProxyRegistrationBean` so that calls to the `init()` method no longer trigger early bean initialization. See gh-6178 --- ...DelegatingFilterProxyRegistrationBean.java | 11 ++++- ...atingFilterProxyRegistrationBeanTests.java | 43 ++++++++++++++++++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBean.java b/spring-boot/src/main/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBean.java index 9da12a0d68a..eb98128436e 100644 --- a/spring-boot/src/main/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBean.java @@ -18,6 +18,7 @@ package org.springframework.boot.web.servlet; import javax.servlet.Filter; import javax.servlet.ServletContext; +import javax.servlet.ServletException; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -84,7 +85,15 @@ public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistr @Override 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() { diff --git a/spring-boot/src/test/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBeanTests.java b/spring-boot/src/test/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBeanTests.java index 9a3a5041e07..1aee35c2014 100644 --- a/spring-boot/src/test/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBeanTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/web/servlet/DelegatingFilterProxyRegistrationBeanTests.java @@ -16,15 +16,26 @@ package org.springframework.boot.web.servlet; +import java.io.IOException; + 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.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.test.util.ReflectionTestUtils; -import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.filter.DelegatingFilterProxy; +import org.springframework.web.filter.GenericFilterBean; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.isA; @@ -37,7 +48,9 @@ import static org.mockito.Matchers.isA; public class DelegatingFilterProxyRegistrationBeanTests extends AbstractFilterRegistrationBeanTests { - private WebApplicationContext applicationContext = new GenericWebApplicationContext( + private static ThreadLocal mockFilterInitialized = new ThreadLocal(); + + private GenericWebApplicationContext applicationContext = new GenericWebApplicationContext( new MockServletContext()); @Test @@ -71,6 +84,19 @@ public class DelegatingFilterProxyRegistrationBeanTests .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 public void createServletRegistrationBeanMustNotBeNull() throws Exception { this.thrown.expect(IllegalArgumentException.class); @@ -93,4 +119,17 @@ public class DelegatingFilterProxyRegistrationBeanTests 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 { + } + + } + }