[bs-14] Ensure all servlet context initializers are called

Misuse of TreeSet in EmbeddedWebApplicationContext corrected
(use List and Comparator instead of TreeSet).

[Fixes #48055339]
This commit is contained in:
Dave Syer 2013-04-24 10:14:22 +01:00
parent fb6b224470
commit 8a4b50e289
2 changed files with 28 additions and 14 deletions

View File

@ -18,13 +18,12 @@ package org.springframework.bootstrap.context.embedded;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.Servlet; import javax.servlet.Servlet;
@ -194,7 +193,7 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
if (initializers.isEmpty()) { if (initializers.isEmpty()) {
SortedSet<Entry<String, Servlet>> servletBeans = getOrderedBeansOfType(Servlet.class); List<Entry<String, Servlet>> servletBeans = getOrderedBeansOfType(Servlet.class);
for (Entry<String, Servlet> servletBean : servletBeans) { for (Entry<String, Servlet> servletBean : servletBeans) {
String url = (servletBeans.size() == 1 ? "/" : "/" String url = (servletBeans.size() == 1 ? "/" : "/"
+ servletBean.getKey().toLowerCase() + "/*"); + servletBean.getKey().toLowerCase() + "/*");
@ -258,16 +257,17 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
} }
} }
private <T> SortedSet<Entry<String, T>> getOrderedBeansOfType(Class<T> type) { private <T> List<Entry<String, T>> getOrderedBeansOfType(Class<T> type) {
SortedSet<Entry<String, T>> beans = new TreeSet<Entry<String, T>>( List<Entry<String, T>> beans = new ArrayList<Entry<String, T>>();
new Comparator<Entry<String, T>>() { Comparator<Entry<String, T>> comparator = new Comparator<Entry<String, T>>() {
@Override @Override
public int compare(Entry<String, T> o1, Entry<String, T> o2) { public int compare(Entry<String, T> o1, Entry<String, T> o2) {
return AnnotationAwareOrderComparator.INSTANCE.compare( return AnnotationAwareOrderComparator.INSTANCE.compare(o1.getValue(),
o1.getValue(), o2.getValue()); o2.getValue());
} }
}); };
beans.addAll(getBeanFactory().getBeansOfType(type, true, true).entrySet()); beans.addAll(getBeanFactory().getBeansOfType(type, true, true).entrySet());
Collections.sort(beans, comparator);
return beans; return beans;
} }

View File

@ -33,8 +33,6 @@ import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.bootstrap.context.embedded.EmbeddedWebApplicationContext;
import org.springframework.bootstrap.context.embedded.FilterRegistrationBean;
import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationContextException;
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@ -244,6 +242,22 @@ public class EmbeddedWebApplicationContextTests {
ordered.verify(initializer2).onStartup(servletContext); ordered.verify(initializer2).onStartup(servletContext);
} }
@Test
public void unorderedServletContextInitializerBeans() throws Exception {
addEmbeddedServletContainerFactoryBean();
ServletContextInitializer initializer1 = mock(ServletContextInitializer.class);
ServletContextInitializer initializer2 = mock(ServletContextInitializer.class);
this.context.registerBeanDefinition("initializerBean2",
beanDefinition(initializer2));
this.context.registerBeanDefinition("initializerBean1",
beanDefinition(initializer1));
this.context.refresh();
ServletContext servletContext = getEmbeddedServletContainerFactory()
.getServletContext();
verify(initializer1).onStartup(servletContext);
verify(initializer2).onStartup(servletContext);
}
@Test @Test
public void servletContextInitializerBeansSkipsServletsAndFilters() throws Exception { public void servletContextInitializerBeansSkipsServletsAndFilters() throws Exception {
addEmbeddedServletContainerFactoryBean(); addEmbeddedServletContainerFactoryBean();