diff --git a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java index 9125716580d..d6eeabf7e90 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java @@ -27,7 +27,7 @@ import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.core.OrderComparator; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.io.UrlResource; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -48,12 +48,13 @@ import org.springframework.util.StringUtils; * * @author Arjen Poutsma * @author Juergen Hoeller + * @author Sam Brannen * @since 3.2 */ public abstract class SpringFactoriesLoader { /** The location to look for the factories. Can be present in multiple JAR files. */ - private static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; + public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class); @@ -61,7 +62,7 @@ public abstract class SpringFactoriesLoader { /** * Load the factory implementations of the given type from the default location, * using the given class loader. - *

The returned factories are ordered in accordance with the {@link OrderComparator}. + *

The returned factories are ordered in accordance with the {@link AnnotationAwareOrderComparator}. * @param factoryClass the interface or abstract class representing the factory * @param classLoader the ClassLoader to use for loading (can be {@code null} to use the default) */ @@ -79,7 +80,7 @@ public abstract class SpringFactoriesLoader { for (String factoryName : factoryNames) { result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse)); } - OrderComparator.sort(result); + AnnotationAwareOrderComparator.sort(result); return result; } diff --git a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java index b3dbceb10c4..6e1386fe33a 100644 --- a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java @@ -79,6 +79,7 @@ public class MergedContextConfiguration implements Serializable { private final String[] propertySourceProperties; private final ContextLoader contextLoader; private final CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate; + private final MergedContextConfiguration parent; @@ -185,6 +186,18 @@ public class MergedContextConfiguration implements Serializable { cacheAwareContextLoaderDelegate, parent); } + /** + * Create a new {@code MergedContextConfiguration} instance by copying + * all fields from the supplied {@code MergedContextConfiguration}. + * @since 4.1 + */ + public MergedContextConfiguration(MergedContextConfiguration mergedConfig) { + this(mergedConfig.testClass, mergedConfig.locations, mergedConfig.classes, + mergedConfig.contextInitializerClasses, mergedConfig.activeProfiles, mergedConfig.propertySourceLocations, + mergedConfig.propertySourceProperties, mergedConfig.contextLoader, + mergedConfig.cacheAwareContextLoaderDelegate, mergedConfig.parent); + } + /** * Create a new {@code MergedContextConfiguration} instance for the * supplied parameters. diff --git a/spring-test/src/main/java/org/springframework/test/context/TestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/TestContextBootstrapper.java index 72c1be0acaa..a61bb7cf009 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestContextBootstrapper.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestContextBootstrapper.java @@ -63,8 +63,16 @@ public interface TestContextBootstrapper { * for the test class in the {@link BootstrapContext} associated with this bootstrapper. *

If {@link TestExecutionListeners @TestExecutionListeners} is not * present on the test class in the {@code BootstrapContext}, - * default listeners should be returned. Concrete implementations - * are free to determine what comprises the set of default listeners. + * default listeners should be returned. Furthermore, default + * listeners must be sorted using + * {@link org.springframework.core.annotation.AnnotationAwareOrderComparator + * AnnotationAwareOrderComparator}. + *

Concrete implementations are free to determine what comprises the + * set of default listeners. However, by default, the Spring TestContext + * Framework will use the + * {@link org.springframework.core.io.support.SpringFactoriesLoader SpringFactoriesLoader} + * mechanism to look up all {@code TestExecutionListener} class names + * configured in all {@code META-INF/spring.factories} files on the classpath. *

The {@link TestExecutionListeners#inheritListeners() inheritListeners} * flag of {@link TestExecutionListeners @TestExecutionListeners} must be * taken into consideration. Specifically, if the {@code inheritListeners} diff --git a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java index 74b9ee5f6c4..8eb58591d5a 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java @@ -23,7 +23,13 @@ package org.springframework.test.context; *

Concrete implementations must provide a {@code public} no-args constructor, * so that listeners can be instantiated transparently by tools and configuration * mechanisms. - *

Spring provides the following out-of-the-box implementations: + *

Implementations may optionally declare the position in which they should + * be ordered among the chain of default listeners via the + * {@link org.springframework.core.Ordered Order} interface or + * {@link org.springframework.core.annotation.Order @Order} annotation. See + * {@link TestContextBootstrapper#getTestExecutionListeners()} for details. + *

Spring provides the following out-of-the-box implementations (all of + * which are annotated with {@code @Order}): *