diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java index f50c0e2a93..9087bdbeaf 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java @@ -91,10 +91,8 @@ public @interface ContextConfiguration { /** * Alias for {@link #locations}. - * *
This attribute may not be used in conjunction with * {@link #locations}, but it may be used instead of {@link #locations}. - * * @since 3.0 * @see #inheritLocations */ @@ -104,7 +102,6 @@ public @interface ContextConfiguration { /** * The resource locations to use for loading an * {@link org.springframework.context.ApplicationContext ApplicationContext}. - * *
Check out the Javadoc for * {@link org.springframework.test.context.support.AbstractContextLoader#modifyLocations * AbstractContextLoader.modifyLocations()} for details on how a location @@ -113,7 +110,6 @@ public @interface ContextConfiguration { * {@link org.springframework.test.context.support.AbstractContextLoader#generateDefaultLocations * AbstractContextLoader.generateDefaultLocations()} for details on the * default locations that are going to be used if none are specified. - * *
Note that the aforementioned default rules only apply for a standard * {@link org.springframework.test.context.support.AbstractContextLoader * AbstractContextLoader} subclass such as @@ -122,10 +118,8 @@ public @interface ContextConfiguration { * which are the effective default implementations used at runtime if * {@code locations} are configured. See the documentation for {@link #loader} * for further details regarding default loaders. - * *
This attribute may not be used in conjunction with * {@link #value}, but it may be used instead of {@link #value}. - * * @since 2.5 * @see #inheritLocations */ @@ -135,14 +129,12 @@ public @interface ContextConfiguration { /** * The annotated classes to use for loading an * {@link org.springframework.context.ApplicationContext ApplicationContext}. - * - *
Check out the Javadoc for + *
Check out the javadoc for * {@link org.springframework.test.context.support.AnnotationConfigContextLoader#detectDefaultConfigurationClasses * AnnotationConfigContextLoader.detectDefaultConfigurationClasses()} for details * on how default configuration classes will be detected if no * annotated classes are specified. See the documentation for * {@link #loader} for further details regarding default loaders. - * * @since 3.1 * @see org.springframework.context.annotation.Configuration * @see org.springframework.test.context.support.AnnotationConfigContextLoader @@ -153,16 +145,13 @@ public @interface ContextConfiguration { /** * The application context initializer classes to use for initializing * a {@link ConfigurableApplicationContext}. - * *
The concrete {@code ConfigurableApplicationContext} type supported by each * declared initializer must be compatible with the type of {@code ApplicationContext} * created by the {@link SmartContextLoader} in use. - * *
{@code SmartContextLoader} implementations typically detect whether * Spring's {@link org.springframework.core.Ordered Ordered} interface has been * implemented or if the @{@link org.springframework.core.annotation.Order Order} * annotation is present and sort instances accordingly prior to invoking them. - * * @since 3.2 * @see org.springframework.context.ApplicationContextInitializer * @see org.springframework.context.ConfigurableApplicationContext @@ -174,7 +163,6 @@ public @interface ContextConfiguration { /** * Whether or not {@link #locations resource locations} or annotated * classes from test superclasses should be inherited. - * *
The default value is {@code true}. This means that an annotated * class will inherit the resource locations or annotated classes * defined by test superclasses. Specifically, the resource locations or @@ -182,12 +170,10 @@ public @interface ContextConfiguration { * resource locations or annotated classes defined by test superclasses. * Thus, subclasses have the option of extending the list of resource * locations or annotated classes. - * *
If {@code inheritLocations} is set to {@code false}, the * resource locations or annotated classes for the annotated class * will shadow and effectively replace any resource locations * or annotated classes defined by superclasses. - * *
In the following example that uses path-based resource locations, the * {@link org.springframework.context.ApplicationContext ApplicationContext} * for {@code ExtendedTest} will be loaded from @@ -206,7 +192,6 @@ public @interface ContextConfiguration { * // ... * } * - * *
Similarly, in the following example that uses annotated * classes, the * {@link org.springframework.context.ApplicationContext ApplicationContext} @@ -233,18 +218,15 @@ public @interface ContextConfiguration { /** * Whether or not {@linkplain #initializers context initializers} from test * superclasses should be inherited. - * *
The default value is {@code true}. This means that an annotated * class will inherit the application context initializers defined * by test superclasses. Specifically, the initializers for a given test * class will be added to the set of initializers defined by test * superclasses. Thus, subclasses have the option of extending the * set of initializers. - * *
If {@code inheritInitializers} is set to {@code false}, the * initializers for the annotated class will shadow and effectively * replace any initializers defined by superclasses. - * *
In the following example, the * {@link org.springframework.context.ApplicationContext ApplicationContext} * for {@code ExtendedTest} will be initialized using @@ -272,12 +254,10 @@ public @interface ContextConfiguration { * The type of {@link SmartContextLoader} (or {@link ContextLoader}) to use * for loading an {@link org.springframework.context.ApplicationContext * ApplicationContext}. - * *
If not specified, the loader will be inherited from the first superclass * that is annotated with {@code @ContextConfiguration} and specifies an * explicit loader. If no class in the hierarchy specifies an explicit * loader, a default loader will be used instead. - * *
The default concrete implementation chosen at runtime will be either * {@link org.springframework.test.context.support.DelegatingSmartContextLoader * DelegatingSmartContextLoader} or @@ -293,23 +273,19 @@ public @interface ContextConfiguration { * {@link org.springframework.test.context.web.GenericXmlWebContextLoader GenericXmlWebContextLoader}, * {@link org.springframework.test.context.web.GenericGroovyXmlWebContextLoader GenericGroovyXmlWebContextLoader}, and * {@link org.springframework.test.context.web.AnnotationConfigWebContextLoader AnnotationConfigWebContextLoader}. - * * @since 2.5 */ Class extends ContextLoader> loader() default ContextLoader.class; /** * The name of the context hierarchy level represented by this configuration. - * *
If not specified the name will be inferred based on the numerical level * within all declared contexts within the hierarchy. - * *
This attribute is only applicable when used within a test class hierarchy * that is configured using {@code @ContextHierarchy}, in which case the name * can be used for merging or overriding this configuration * with configuration of the same name in hierarchy levels defined in superclasses. * See the Javadoc for {@link ContextHierarchy @ContextHierarchy} for details. - * * @since 3.2.2 */ String name() default ""; diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextHierarchy.java b/spring-test/src/main/java/org/springframework/test/context/ContextHierarchy.java index 813fd30672..61b2fa8cf6 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextHierarchy.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextHierarchy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -148,7 +148,6 @@ public @interface ContextHierarchy { /** * A list of {@link ContextConfiguration @ContextConfiguration} instances, * each of which defines a level in the context hierarchy. - * *
If you need to merge or override the configuration for a given level * of the context hierarchy within a test class hierarchy, you must explicitly * name that level by supplying the same value to the {@link ContextConfiguration#name diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java index 71faf5e522..3a2b0c300e 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,7 @@ import org.springframework.context.ApplicationContext; * The results of {@link #processLocations(Class, String...) processLocations()} * should then be supplied to {@link #loadContext(String...) loadContext()}. * - *
Concrete implementations must provide a {@code public} no-args - * constructor. + *
Concrete implementations must provide a {@code public} no-args constructor. * *
Spring provides the following out-of-the-box implementations: *
Concrete implementations may choose to modify the supplied locations, * generate new locations, or simply return the supplied locations unchanged. - * * @param clazz the class with which the locations are associated: used to * determine how to process the supplied locations * @param locations the unmodified locations to use for loading the @@ -68,10 +65,8 @@ public interface ContextLoader { * Loads a new {@link ApplicationContext context} based on the supplied * {@code locations}, configures the context, and finally returns * the context in fully refreshed state. - * *
Configuration locations are generally considered to be classpath * resources by default. - * *
Concrete implementations should register annotation configuration * processors with bean factories of {@link ApplicationContext application * contexts} loaded by this ContextLoader. Beans will therefore automatically @@ -79,13 +74,11 @@ public interface ContextLoader { * {@link org.springframework.beans.factory.annotation.Autowired @Autowired}, * {@link javax.annotation.Resource @Resource}, and * {@link javax.inject.Inject @Inject}. - * *
Any ApplicationContext loaded by a ContextLoader must * register a JVM shutdown hook for itself. Unless the context gets closed * early, all context instances will be automatically closed on JVM * shutdown. This allows for freeing external resources held by beans within * the context, e.g. temporary files. - * * @param locations the resource locations to use to load the application context * @return a new application context * @throws Exception if context loading failed diff --git a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java index d86585d733..da3383cb37 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java @@ -57,17 +57,12 @@ abstract class ContextLoaderUtils { private static final Log logger = LogFactory.getLog(ContextLoaderUtils.class); - private ContextLoaderUtils() { - /* no-op */ - } - /** * Resolve the list of lists of {@linkplain ContextConfigurationAttributes context * configuration attributes} for the supplied {@linkplain Class test class} and its * superclasses, taking into account context hierarchies declared via * {@link ContextHierarchy @ContextHierarchy} and * {@link ContextConfiguration @ContextConfiguration}. - * *
The outer list represents a top-down ordering of context configuration * attributes, where each element in the list represents the context configuration * declared on a given test class in the class hierarchy. Each nested list @@ -77,13 +72,11 @@ abstract class ContextLoaderUtils { * single {@code @ContextHierarchy} instance on the particular class. * Furthermore, each nested list maintains the order in which * {@code @ContextConfiguration} instances are declared. - * *
Note that the {@link ContextConfiguration#inheritLocations inheritLocations} and
* {@link ContextConfiguration#inheritInitializers() inheritInitializers} flags of
* {@link ContextConfiguration @ContextConfiguration} will not
* be taken into consideration. If these flags need to be honored, that must be
* handled manually when traversing the nested lists returned by this method.
- *
* @param testClass the class for which to resolve the context hierarchy attributes
* (must not be {@code null})
* @return the list of lists of configuration attributes for the specified class;
@@ -95,7 +88,6 @@ abstract class ContextLoaderUtils {
* {@code @ContextHierarchy} as top-level annotations.
* @throws IllegalStateException if no class in the class hierarchy declares
* {@code @ContextHierarchy}.
- *
* @since 3.2.2
* @see #buildContextHierarchyMap(Class)
* @see #resolveContextConfigurationAttributes(Class)
@@ -109,23 +101,25 @@ abstract class ContextLoaderUtils {
final Class Each value in the map represents the consolidated list of {@linkplain
* ContextConfigurationAttributes context configuration attributes} for a
* given level in the context hierarchy (potentially across the test class
* hierarchy), keyed by the {@link ContextConfiguration#name() name} of the
* context hierarchy level.
- *
* If a given level in the context hierarchy does not have an explicit
* name (i.e., configured via {@link ContextConfiguration#name}), a name will
* be generated for that hierarchy level by appending the numerical level to
* the {@link #GENERATED_CONTEXT_HIERARCHY_LEVEL_PREFIX}.
- *
* @param testClass the class for which to resolve the context hierarchy map
* (must not be {@code null})
* @return a map of context configuration attributes for the context hierarchy,
@@ -187,7 +176,6 @@ abstract class ContextLoaderUtils {
* @throws IllegalArgumentException if the lists of context configuration
* attributes for each level in the {@code @ContextHierarchy} do not define
* unique context configuration within the overall hierarchy.
- *
* @since 3.2.2
* @see #resolveContextHierarchyAttributes(Class)
*/
@@ -217,9 +205,9 @@ abstract class ContextLoaderUtils {
// Check for uniqueness
Set Note that the {@link ContextConfiguration#inheritLocations inheritLocations} and
* {@link ContextConfiguration#inheritInitializers() inheritInitializers} flags of
* {@link ContextConfiguration @ContextConfiguration} will not
* be taken into consideration. If these flags need to be honored, that must be
* handled manually when traversing the list returned by this method.
- *
- * @param testClass the class for which to resolve the configuration attributes (must
- * not be {@code null})
+ * @param testClass the class for which to resolve the configuration attributes
+ * (must not be {@code null})
* @return the list of configuration attributes for the specified class, ordered
* bottom-up (i.e., as if we were traversing up the class hierarchy);
* never {@code null}
@@ -249,18 +235,19 @@ abstract class ContextLoaderUtils {
static List> hierarchyAttributes = new ArrayList
>();
- UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(testClass, contextConfigType,
- contextHierarchyType);
- Assert.notNull(descriptor, String.format(
- "Could not find an 'annotation declaring class' for annotation type [%s] or [%s] and test class [%s]",
- contextConfigType.getName(), contextHierarchyType.getName(), testClass.getName()));
+ UntypedAnnotationDescriptor desc =
+ findAnnotationDescriptorForTypes(testClass, contextConfigType, contextHierarchyType);
+ if (desc == null) {
+ throw new IllegalArgumentException(String.format(
+ "Could not find an 'annotation declaring class' for annotation type [%s] or [%s] and test class [%s]",
+ contextConfigType.getName(), contextHierarchyType.getName(), testClass.getName()));
+ }
- while (descriptor != null) {
- Class> rootDeclaringClass = descriptor.getRootDeclaringClass();
- Class> declaringClass = descriptor.getDeclaringClass();
+ while (desc != null) {
+ Class> rootDeclaringClass = desc.getRootDeclaringClass();
+ Class> declaringClass = desc.getDeclaringClass();
boolean contextConfigDeclaredLocally = isAnnotationDeclaredLocally(contextConfigType, declaringClass);
boolean contextHierarchyDeclaredLocally = isAnnotationDeclaredLocally(contextHierarchyType, declaringClass);
if (contextConfigDeclaredLocally && contextHierarchyDeclaredLocally) {
- String msg = String.format("Class [%s] has been configured with both @ContextConfiguration "
- + "and @ContextHierarchy. Only one of these annotations may be declared on a test class "
- + "or composed annotation.", declaringClass.getName());
+ String msg = String.format("Class [%s] has been configured with both @ContextConfiguration " +
+ "and @ContextHierarchy. Only one of these annotations may be declared on a test class " +
+ "or composed annotation.", declaringClass.getName());
logger.error(msg);
throw new IllegalStateException(msg);
}
@@ -134,30 +128,28 @@ abstract class ContextLoaderUtils {
if (contextConfigDeclaredLocally) {
ContextConfiguration contextConfiguration = AnnotationUtils.synthesizeAnnotation(
- descriptor.getAnnotationAttributes(), ContextConfiguration.class,
- descriptor.getRootDeclaringClass());
- convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, rootDeclaringClass,
- configAttributesList);
+ desc.getAnnotationAttributes(), ContextConfiguration.class, desc.getRootDeclaringClass());
+ convertContextConfigToConfigAttributesAndAddToList(
+ contextConfiguration, rootDeclaringClass, configAttributesList);
}
else if (contextHierarchyDeclaredLocally) {
ContextHierarchy contextHierarchy = getAnnotation(declaringClass, contextHierarchyType);
for (ContextConfiguration contextConfiguration : contextHierarchy.value()) {
- convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, rootDeclaringClass,
- configAttributesList);
+ convertContextConfigToConfigAttributesAndAddToList(
+ contextConfiguration, rootDeclaringClass, configAttributesList);
}
}
else {
// This should theoretically never happen...
- String msg = String.format("Test class [%s] has been configured with neither @ContextConfiguration "
- + "nor @ContextHierarchy as a class-level annotation.", rootDeclaringClass.getName());
+ String msg = String.format("Test class [%s] has been configured with neither @ContextConfiguration " +
+ "nor @ContextHierarchy as a class-level annotation.", rootDeclaringClass.getName());
logger.error(msg);
throw new IllegalStateException(msg);
}
hierarchyAttributes.add(0, configAttributesList);
-
- descriptor = findAnnotationDescriptorForTypes(rootDeclaringClass.getSuperclass(), contextConfigType,
- contextHierarchyType);
+ desc = findAnnotationDescriptorForTypes(
+ rootDeclaringClass.getSuperclass(), contextConfigType, contextHierarchyType);
}
return hierarchyAttributes;
@@ -168,18 +160,15 @@ abstract class ContextLoaderUtils {
* test class} and its superclasses, taking into account context hierarchies
* declared via {@link ContextHierarchy @ContextHierarchy} and
* {@link ContextConfiguration @ContextConfiguration}.
- *
*
> set = new HashSet
>(map.values());
if (set.size() != map.size()) {
- String msg = String.format("The @ContextConfiguration elements configured via "
- + "@ContextHierarchy in test class [%s] and its superclasses must "
- + "define unique contexts per hierarchy level.", testClass.getName());
+ String msg = String.format("The @ContextConfiguration elements configured via @ContextHierarchy in " +
+ "test class [%s] and its superclasses must define unique contexts per hierarchy level.",
+ testClass.getName());
logger.error(msg);
throw new IllegalStateException(msg);
}
@@ -231,15 +219,13 @@ abstract class ContextLoaderUtils {
* Resolve the list of {@linkplain ContextConfigurationAttributes context
* configuration attributes} for the supplied {@linkplain Class test class} and its
* superclasses.
- *
*