diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistration.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistration.java index df3f67644560..fdb4916b8293 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistration.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/FilterRegistration.java @@ -24,6 +24,7 @@ import jakarta.servlet.DispatcherType; import jakarta.servlet.Filter; +import jakarta.servlet.annotation.WebInitParam; import org.springframework.core.Ordered; import org.springframework.core.annotation.AliasFor; @@ -34,6 +35,7 @@ * annotation-based alternative to {@link FilterRegistrationBean}. * * @author Moritz Halbritter + * @author Daeho Kwon * @since 3.5.0 * @see FilterRegistrationBean */ @@ -81,6 +83,12 @@ */ boolean ignoreRegistrationFailure() default false; + /** + * Init parameters to be used with the filter. + * @return the init parameters + */ + WebInitParam[] initParameters() default {}; + /** * Whether the filter mappings should be matched after any declared Filter mappings of * the ServletContext. @@ -95,6 +103,12 @@ */ String[] servletNames() default {}; + /** + * Servlet types that the filter will be registered against. + * @return the servlet types + */ + Class[] servletRegistrationBeans() default {}; + /** * URL patterns, as defined in the Servlet specification, that the filter will be * registered against. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializerBeans.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializerBeans.java index f8cb5dd03572..5d2d03cb4649 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializerBeans.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializerBeans.java @@ -35,6 +35,7 @@ import jakarta.servlet.Filter; import jakarta.servlet.MultipartConfigElement; import jakarta.servlet.Servlet; +import jakarta.servlet.annotation.WebInitParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -63,6 +64,7 @@ * @author Phillip Webb * @author Brian Clozel * @author Moritz Halbritter + * @author Daeho Kwon * @since 1.4.0 */ public class ServletContextInitializerBeans extends AbstractCollection { @@ -362,6 +364,17 @@ private void configureFromAnnotation(FilterRegistrationBean bean, Filter bean.setMatchAfter(registration.matchAfter()); bean.setServletNames(Arrays.asList(registration.servletNames())); bean.setUrlPatterns(Arrays.asList(registration.urlPatterns())); + for (WebInitParam param : registration.initParameters()) { + bean.addInitParameter(param.name(), param.value()); + } + + this.beanFactory.getBeanProvider(ServletRegistrationBean.class).forEach((servletRegistrationBean) -> { + for (Class servletClass : registration.servletRegistrationBeans()) { + if (servletClass.isInstance(servletRegistrationBean.getServlet())) { + bean.addServletRegistrationBeans(servletRegistrationBean); + } + } + }); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletContextInitializerBeansTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletContextInitializerBeansTests.java index 0d6b2389e6ea..44c03bbdca55 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletContextInitializerBeansTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletContextInitializerBeansTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.web.servlet; +import java.util.Collection; import java.util.EnumSet; import jakarta.servlet.DispatcherType; @@ -25,6 +26,7 @@ import jakarta.servlet.ServletContext; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; +import jakarta.servlet.annotation.WebInitParam; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -47,6 +49,7 @@ * * @author Andy Wilkinson * @author Moritz Halbritter + * @author Daeho Kwon */ class ServletContextInitializerBeansTests { @@ -141,6 +144,14 @@ void shouldApplyFilterRegistrationAnnotation() { assertThat(filterRegistrationBean.getServletNames()).containsExactly("test"); assertThat(filterRegistrationBean.determineDispatcherTypes()).containsExactly(DispatcherType.ERROR); assertThat(filterRegistrationBean.getUrlPatterns()).containsExactly("/test/*"); + assertThat(filterRegistrationBean.getInitParameters()).containsEntry("env", "test") + .containsEntry("debug", "true"); + Collection> servletRegistrationBeans = filterRegistrationBean + .getServletRegistrationBeans(); + assertThat(servletRegistrationBeans).hasSize(1); + assertThat(servletRegistrationBeans.iterator().next().getServletName()) + .isEqualTo("testServletRegistrationBean"); + }); } @@ -296,11 +307,33 @@ static class FilterConfigurationWithAnnotation { @Bean @FilterRegistration(enabled = false, name = "test", asyncSupported = false, dispatcherTypes = DispatcherType.ERROR, matchAfter = true, servletNames = "test", - urlPatterns = "/test/*") + urlPatterns = "/test/*", + initParameters = { @WebInitParam(name = "env", value = "test"), + @WebInitParam(name = "debug", value = "true") }, + servletRegistrationBeans = { TestServlet.class }) TestFilter testFilter() { return new TestFilter(); } + @Bean + ServletRegistrationBean testServletRegistrationBean() { + return new ServletRegistrationBean<>(new TestServlet()); + } + + @Bean + ServletRegistrationBean nonMatchingServletRegistrationBean() { + return new ServletRegistrationBean<>(new NonMatchingServlet()); + } + + static class NonMatchingServlet extends HttpServlet implements ServletContextInitializer { + + @Override + public void onStartup(ServletContext servletContext) { + + } + + } + } @Configuration(proxyBeanMethods = false)