Skip to content

Commit 47b5904

Browse files
author
Dave Syer
committed
Order Filters, Servlets etc. separately in EmbeddedWebApplicationContext
Users could be surpised if they register a Filter with an @order and it isn't apparently respected. This change accumulates all Filters and FilterRegistrations (for instance) before sorting them. Fixes gh-1455
1 parent 1ddcf36 commit 47b5904

File tree

2 files changed

+78
-9
lines changed

2 files changed

+78
-9
lines changed

spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContext.java

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -225,27 +225,35 @@ public void onStartup(ServletContext servletContext) throws ServletException {
225225
*/
226226
protected Collection<ServletContextInitializer> getServletContextInitializerBeans() {
227227

228-
Set<ServletContextInitializer> initializers = new LinkedHashSet<ServletContextInitializer>();
228+
List<ServletContextInitializer> filters = new ArrayList<ServletContextInitializer>();
229+
List<ServletContextInitializer> servlets = new ArrayList<ServletContextInitializer>();
230+
List<ServletContextInitializer> listeners = new ArrayList<ServletContextInitializer>();
231+
List<ServletContextInitializer> other = new ArrayList<ServletContextInitializer>();
229232
Set<Servlet> servletRegistrations = new LinkedHashSet<Servlet>();
230233
Set<Filter> filterRegistrations = new LinkedHashSet<Filter>();
231234
Set<EventListener> listenerRegistrations = new LinkedHashSet<EventListener>();
232235

233236
for (Entry<String, ServletContextInitializer> initializerBean : getOrderedBeansOfType(ServletContextInitializer.class)) {
234237
ServletContextInitializer initializer = initializerBean.getValue();
235-
initializers.add(initializer);
236238
if (initializer instanceof ServletRegistrationBean) {
239+
servlets.add(initializer);
237240
ServletRegistrationBean servlet = (ServletRegistrationBean) initializer;
238241
servletRegistrations.add(servlet.getServlet());
239242
}
240-
if (initializer instanceof FilterRegistrationBean) {
243+
else if (initializer instanceof FilterRegistrationBean) {
244+
filters.add(initializer);
241245
FilterRegistrationBean filter = (FilterRegistrationBean) initializer;
242246
filterRegistrations.add(filter.getFilter());
243247
}
244-
if (initializer instanceof ServletListenerRegistrationBean) {
248+
else if (initializer instanceof ServletListenerRegistrationBean) {
249+
listeners.add(initializer);
245250
listenerRegistrations
246251
.add(((ServletListenerRegistrationBean<?>) initializer)
247252
.getListener());
248253
}
254+
else {
255+
other.add(initializer);
256+
}
249257
}
250258

251259
List<Entry<String, Servlet>> servletBeans = getOrderedBeansOfType(Servlet.class);
@@ -261,7 +269,9 @@ protected Collection<ServletContextInitializer> getServletContextInitializerBean
261269
servlet, url);
262270
registration.setName(name);
263271
registration.setMultipartConfig(getMultipartConfig());
264-
initializers.add(registration);
272+
registration.setOrder(CustomOrderAwareComparator.INSTANCE
273+
.getOrder(servlet));
274+
servlets.add(registration);
265275
}
266276
}
267277

@@ -271,7 +281,9 @@ protected Collection<ServletContextInitializer> getServletContextInitializerBean
271281
if (!filterRegistrations.contains(filter)) {
272282
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
273283
registration.setName(name);
274-
initializers.add(registration);
284+
registration.setOrder(CustomOrderAwareComparator.INSTANCE
285+
.getOrder(filter));
286+
filters.add(registration);
275287
}
276288
}
277289

@@ -285,12 +297,23 @@ protected Collection<ServletContextInitializer> getServletContextInitializerBean
285297
ServletListenerRegistrationBean<EventListener> registration = new ServletListenerRegistrationBean<EventListener>(
286298
listener);
287299
registration.setName(name);
288-
initializers.add(registration);
300+
registration.setOrder(CustomOrderAwareComparator.INSTANCE
301+
.getOrder(listener));
302+
listeners.add(registration);
289303
}
290304
}
291305
}
292-
293-
return initializers;
306+
AnnotationAwareOrderComparator.sort(filters);
307+
AnnotationAwareOrderComparator.sort(servlets);
308+
AnnotationAwareOrderComparator.sort(listeners);
309+
AnnotationAwareOrderComparator.sort(other);
310+
311+
List<ServletContextInitializer> list = new ArrayList<ServletContextInitializer>(
312+
filters);
313+
list.addAll(servlets);
314+
list.addAll(listeners);
315+
list.addAll(other);
316+
return list;
294317
}
295318

296319
private MultipartConfigElement getMultipartConfig() {
@@ -425,4 +448,15 @@ public EmbeddedServletContainer getEmbeddedServletContainer() {
425448
return this.embeddedServletContainer;
426449
}
427450

451+
private static class CustomOrderAwareComparator extends
452+
AnnotationAwareOrderComparator {
453+
454+
public static CustomOrderAwareComparator INSTANCE = new CustomOrderAwareComparator();
455+
456+
@Override
457+
protected int getOrder(Object obj) {
458+
return super.getOrder(obj);
459+
}
460+
}
461+
428462
}

spring-boot/src/test/java/org/springframework/boot/context/embedded/EmbeddedWebApplicationContextTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,26 @@
1616

1717
package org.springframework.boot.context.embedded;
1818

19+
import java.io.IOException;
1920
import java.lang.reflect.Field;
2021
import java.util.Properties;
2122

2223
import javax.servlet.Filter;
24+
import javax.servlet.FilterChain;
2325
import javax.servlet.Servlet;
2426
import javax.servlet.ServletContext;
2527
import javax.servlet.ServletContextListener;
28+
import javax.servlet.ServletException;
29+
import javax.servlet.ServletRequest;
30+
import javax.servlet.ServletResponse;
2631

2732
import org.junit.After;
2833
import org.junit.Before;
2934
import org.junit.Rule;
3035
import org.junit.Test;
3136
import org.junit.rules.ExpectedException;
3237
import org.mockito.InOrder;
38+
import org.mockito.Mockito;
3339
import org.springframework.beans.MutablePropertyValues;
3440
import org.springframework.beans.factory.config.BeanDefinition;
3541
import org.springframework.beans.factory.config.ConstructorArgumentValues;
@@ -39,9 +45,11 @@
3945
import org.springframework.context.support.AbstractApplicationContext;
4046
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
4147
import org.springframework.core.Ordered;
48+
import org.springframework.core.annotation.Order;
4249
import org.springframework.web.context.ServletContextAware;
4350
import org.springframework.web.context.WebApplicationContext;
4451
import org.springframework.web.context.request.SessionScope;
52+
import org.springframework.web.filter.GenericFilterBean;
4553

4654
import static org.hamcrest.Matchers.equalTo;
4755
import static org.hamcrest.Matchers.instanceOf;
@@ -192,6 +200,23 @@ public void singleServletBean() throws Exception {
192200
verify(escf.getRegisteredServlet(0).getRegistration()).addMapping("/");
193201
}
194202

203+
@Test
204+
public void orderedBeanInsertedCorrectly() throws Exception {
205+
addEmbeddedServletContainerFactoryBean();
206+
OrderedFilter filter = new OrderedFilter();
207+
this.context.registerBeanDefinition("filterBean", beanDefinition(filter));
208+
FilterRegistrationBean registration = new FilterRegistrationBean();
209+
registration.setFilter(Mockito.mock(Filter.class));
210+
registration.setOrder(100);
211+
this.context.registerBeanDefinition("filterRegistrationBean",
212+
beanDefinition(registration));
213+
this.context.refresh();
214+
MockEmbeddedServletContainerFactory escf = getEmbeddedServletContainerFactory();
215+
verify(escf.getServletContext()).addFilter("filterBean", filter);
216+
verify(escf.getServletContext()).addFilter("object", registration.getFilter());
217+
assertEquals(filter, escf.getRegisteredFilter(0).getFilter());
218+
}
219+
195220
@Test
196221
public void multipleServletBeans() throws Exception {
197222
addEmbeddedServletContainerFactoryBean();
@@ -422,4 +447,14 @@ public EmbeddedServletContainerInitializedEvent getEvent() {
422447
}
423448

424449
}
450+
451+
@Order(10)
452+
protected static class OrderedFilter extends GenericFilterBean {
453+
454+
@Override
455+
public void doFilter(ServletRequest request, ServletResponse response,
456+
FilterChain chain) throws IOException, ServletException {
457+
}
458+
459+
}
425460
}

0 commit comments

Comments
 (0)