From 72da569aa3c84ade51cac8af84e0206f644746b6 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 20 Aug 2011 23:14:20 +0000 Subject: [PATCH] [SPR-8386][SPR-8387] Revised Javadoc in the TestContext framework regarding changes in 3.1. --- .../test/context/ActiveProfiles.java | 2 +- .../test/context/ContextCache.java | 6 ++-- .../test/context/ContextConfiguration.java | 30 ++++++++--------- .../test/context/ContextLoader.java | 23 ++++++------- .../test/context/SmartContextLoader.java | 7 ++-- .../test/context/TestContext.java | 3 +- .../support/AbstractContextLoader.java | 9 ++++- .../support/AbstractGenericContextLoader.java | 24 +++++++------- .../AnnotationConfigContextLoader.java | 33 ++++++++++--------- .../AnnotationConfigContextLoaderTests.java | 26 +++++++-------- 10 files changed, 87 insertions(+), 76 deletions(-) diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java b/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java index 9b72b5443c6..043581aee26 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java @@ -44,7 +44,7 @@ import java.lang.annotation.Target; public @interface ActiveProfiles { /** - * Alias for {@link #profiles() profiles}. + * Alias for {@link #profiles}. * *

This attribute may not be used in conjunction * with {@link #profiles}, but it may be used instead of diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java b/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java index 9997433d0ca..a2458fa3305 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java @@ -158,9 +158,9 @@ class ContextCache { * {@link #remove removing} the context from the cache and explicitly * {@link ConfigurableApplicationContext#close() closing} it if * it is an instance of {@link ConfigurableApplicationContext}. - *

Generally speaking, you would only call this method only if you change - * the state of a singleton bean, potentially affecting future interaction - * with the context. + *

Generally speaking, you would only call this method if you change the + * state of a singleton bean, potentially affecting future interaction with + * the context. * @param key the context key (never null) * @see #remove */ diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfiguration.java b/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfiguration.java index ec3b2f859bf..623f30b1662 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfiguration.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfiguration.java @@ -41,6 +41,8 @@ import java.lang.annotation.Target; * @since 2.5 * @see ContextLoader * @see SmartContextLoader + * @see ContextConfigurationAttributes + * @see MergedContextConfiguration * @see org.springframework.context.ApplicationContext * @see ActiveProfiles */ @@ -51,7 +53,7 @@ import java.lang.annotation.Target; public @interface ContextConfiguration { /** - * Alias for {@link #locations() locations}. + * Alias for {@link #locations}. * *

This attribute may not be used in conjunction * with {@link #locations} or {@link #classes}, but it may be used @@ -64,7 +66,7 @@ public @interface ContextConfiguration { * The resource locations 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.AbstractContextLoader#modifyLocations * AbstractContextLoader.modifyLocations()} for details on how a location * String will be interpreted at runtime, in particular in case of a relative @@ -78,7 +80,9 @@ public @interface ContextConfiguration { * AbstractContextLoader} subclass such as * {@link org.springframework.test.context.support.GenericXmlContextLoader * GenericXmlContextLoader} which is the effective default implementation - * used at runtime. + * used at runtime if 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} or {@link #classes}, but it may be used instead of @@ -88,20 +92,16 @@ public @interface ContextConfiguration { String[] locations() default {}; /** - * The {@link org.springframework.context.annotation.Configuration configuration classes} - * to use for loading an + * The {@link org.springframework.context.annotation.Configuration + * configuration classes} to use for loading an * {@link org.springframework.context.ApplicationContext ApplicationContext}. * - *

To enable support for configuration class processing, an appropriate - * {@link SmartContextLoader} must be {@link #loader configured}. - * {@link org.springframework.test.context.support.AnnotationConfigContextLoader - * AnnotationConfigContextLoader} is one such loader provided by the Spring Framework. - * - *

Check out the javadoc for - * {@link org.springframework.test.context.support.AnnotationConfigContextLoader#generateDefaultConfigurationClasses - * AnnotationConfigContextLoader.generateDefaultConfigurationClasses()} - * for details on the default configuration classes that will be used if none - * are specified. + *

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 none are specified. + * See the documentation for {@link #loader} for further details regarding + * default loaders. * *

This attribute may not be used in conjunction with * {@link #locations} or {@link #value}. diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java index 1477291a77d..a5d7f173f36 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java @@ -19,11 +19,12 @@ package org.springframework.test.context; import org.springframework.context.ApplicationContext; /** - * Strategy interface for loading an {@link ApplicationContext application context}. + * Strategy interface for loading an {@link ApplicationContext application context} + * for an integration test managed by the Spring TestContext Framework. * - *

Note: as of Spring 3.1, consider implementing {@link SmartContextLoader} - * instead of this interface in order to provide support for configuration classes - * and active bean definition profiles. + *

Note: as of Spring 3.1, implement {@link SmartContextLoader} instead + * of this interface in order to provide support for configuration classes and + * active bean definition profiles. * *

Clients of a ContextLoader should call * {@link #processLocations(Class,String...) processLocations()} prior to @@ -38,7 +39,6 @@ import org.springframework.context.ApplicationContext; *

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

* @@ -46,6 +46,7 @@ import org.springframework.context.ApplicationContext; * @author Juergen Hoeller * @since 2.5 * @see SmartContextLoader + * @see org.springframework.test.context.support.AnnotationConfigContextLoader AnnotationConfigContextLoader */ public interface ContextLoader { @@ -68,12 +69,12 @@ public interface ContextLoader { *

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 be candidates for - * annotation-based dependency injection using - * {@link org.springframework.beans.factory.annotation.Autowired @Autowired} - * and {@link javax.annotation.Resource @Resource}. + * processors with bean factories of {@link ApplicationContext application + * contexts} loaded by this ContextLoader. Beans will therefore automatically + * be candidates for annotation-based dependency injection using + * {@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 diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java index 624031dbed8..fbf6cd31da2 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java @@ -19,7 +19,7 @@ package org.springframework.test.context; import org.springframework.context.ApplicationContext; /** - *

Strategy interface for loading an {@link ApplicationContext application context} + * Strategy interface for loading an {@link ApplicationContext application context} * for an integration test managed by the Spring TestContext Framework. * *

The {@code SmartContextLoader} SPI supersedes the {@link ContextLoader} SPI @@ -34,8 +34,9 @@ import org.springframework.context.ApplicationContext; * processContextConfiguration()} prior to calling * {@link #loadContext(MergedContextConfiguration) loadContext()}. This gives a * {@code SmartContextLoader} the opportunity to provide custom support for - * modifying or generating resource locations or configuration classes. The - * results of {@link #processContextConfiguration(ContextConfigurationAttributes) + * modifying resource locations or detecting default resource locations or + * default configuration classes. The results of + * {@link #processContextConfiguration(ContextConfigurationAttributes) * processContextConfiguration()} should be merged for all classes in the * hierarchy of the root test class and then supplied to * {@link #loadContext(MergedContextConfiguration) loadContext()}. diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java b/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java index 7bf23876f16..7b7426b1049 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java @@ -108,7 +108,8 @@ public class TestContext extends AttributeAccessorSupport { /** * Load an ApplicationContext for this test context using the - * configured {@code ContextLoader} and configuration attributes. + * configured {@code ContextLoader} and merged context configuration. Supports + * both the {@link SmartContextLoader} and {@link ContextLoader} SPIs. * @throws Exception if an error occurs while loading the application context */ private ApplicationContext loadApplicationContext() throws Exception { diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java index c4fcf8a221f..0e71500a1a8 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java @@ -31,7 +31,7 @@ import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; /** - * Abstract application context loader, which provides a basis for all concrete + * Abstract application context loader that provides a basis for all concrete * implementations of the {@link ContextLoader} SPI. Provides a * Template Method based approach for {@link #processLocations processing} * resource locations. @@ -190,6 +190,13 @@ public abstract class AbstractContextLoader implements SmartContextLoader { * Determine whether or not default resource locations should be * generated if the locations provided to * {@link #processLocations()} are null or empty. + *

As of Spring 3.1, the semantics of this method have been overloaded + * to include detection of either default resource locations or default + * configuration classes. Consequently, this method can also be used to + * determine whether or not default configuration classes should be + * detected if the classes present in the + * {@link ContextConfigurationAttributes configuration attributes} supplied + * to {@link #processContextConfiguration()} are null or empty. *

Can be overridden by subclasses to change the default behavior. * @return always true by default * @since 2.5 diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java index 935fc85a3b1..243e10da4d8 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java @@ -68,18 +68,18 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader *

  • Sets the active bean definition profiles from the supplied * MergedContextConfiguration in the * {@link org.springframework.core.env.Environment Environment} of the context.
  • - *
  • Calls {@link #prepareContext(GenericApplicationContext)} to - * prepare the context.
  • - *
  • Calls {@link #customizeBeanFactory(DefaultListableBeanFactory)} to - * allow for customizing the context's DefaultListableBeanFactory.
  • + *
  • Calls {@link #prepareContext()} to allow for customizing the context + * before bean definitions are loaded.
  • + *
  • Calls {@link #customizeBeanFactory()} to allow for customizing the + * context's DefaultListableBeanFactory.
  • *
  • Delegates to {@link #loadBeanDefinitions()} to populate the context * from the configuration locations or classes in the supplied * MergedContextConfiguration.
  • *
  • Delegates to {@link AnnotationConfigUtils} for * {@link AnnotationConfigUtils#registerAnnotationConfigProcessors registering} * annotation configuration processors.
  • - *
  • Calls {@link #customizeContext(GenericApplicationContext)} to allow - * for customizing the context before it is refreshed.
  • + *
  • Calls {@link #customizeContext()} to allow for customizing the context + * before it is refreshed.
  • *
  • {@link ConfigurableApplicationContext#refresh Refreshes} the * context and registers a JVM shutdown hook for it.
  • * @@ -110,18 +110,18 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader *

    Implementation details: *

    diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java index 2c1b6fd222a..9839adc03c9 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java @@ -51,7 +51,7 @@ import org.springframework.util.ObjectUtils; * @author Sam Brannen * @since 3.1 * @see #processContextConfiguration() - * @see #generateDefaultConfigurationClasses() + * @see #detectDefaultConfigurationClasses() * @see #loadBeanDefinitions() */ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader { @@ -65,18 +65,20 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader * Process configuration classes in the supplied {@link ContextConfigurationAttributes}. *

    If the configuration classes are null or empty and * {@link #isGenerateDefaultLocations()} returns true, this - * SmartContextLoader will attempt to - * {@link #generateDefaultConfigurationClasses generate default configuration classes}. - * Otherwise, properties in the supplied configuration attributes will not - * be modified. + * SmartContextLoader will attempt to {@link + * #detectDefaultConfigurationClasses detect default configuration classes}. + * If defaults are detected they will be + * {@link ContextConfigurationAttributes#setClasses(Class[]) set} in the + * supplied configuration attributes. Otherwise, properties in the supplied + * configuration attributes will not be modified. * @param configAttributes the context configuration attributes to process * @see org.springframework.test.context.SmartContextLoader#processContextConfiguration() * @see #isGenerateDefaultLocations() - * @see #generateDefaultConfigurationClasses() + * @see #detectDefaultConfigurationClasses() */ public void processContextConfiguration(ContextConfigurationAttributes configAttributes) { if (ObjectUtils.isEmpty(configAttributes.getClasses()) && isGenerateDefaultLocations()) { - Class[] defaultConfigClasses = generateDefaultConfigurationClasses(configAttributes.getDeclaringClass()); + Class[] defaultConfigClasses = detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()); configAttributes.setClasses(defaultConfigClasses); } } @@ -108,24 +110,23 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader } /** - * Generate the default configuration class array for the supplied test class. - *

    The generated class array will contain all static inner classes of + * Detect the default configuration classes for the supplied test class. + *

    The returned class array will contain all static inner classes of * the supplied class that meet the requirements for {@code @Configuration} * class implementations as specified in the documentation for * {@link Configuration @Configuration}. *

    The implementation of this method adheres to the contract defined in the * {@link org.springframework.test.context.SmartContextLoader SmartContextLoader} - * SPI. Specifically, this method will preemptively verify that the - * generated default configuration classes exist and that such classes - * comply with the constraints required of {@code @Configuration} class - * implementations. If a candidate configuration class does meet these - * requirements, this method will log a warning, and the candidate class will - * be ignored. + * SPI. Specifically, this method uses introspection to detect default + * configuration classes that comply with the constraints required of + * {@code @Configuration} class implementations. If a potential candidate + * configuration class does meet these requirements, this method will log a + * warning, and the potential candidate class will be ignored. * @param declaringClass the test class that declared {@code @ContextConfiguration} * @return an array of default configuration classes, potentially empty but * never null */ - protected Class[] generateDefaultConfigurationClasses(Class declaringClass) { + protected Class[] detectDefaultConfigurationClasses(Class declaringClass) { Assert.notNull(declaringClass, "Declaring class must not be null"); List> configClasses = new ArrayList>(); diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/support/AnnotationConfigContextLoaderTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/support/AnnotationConfigContextLoaderTests.java index 1a6bd2c4da3..8cc52762862 100644 --- a/org.springframework.test/src/test/java/org/springframework/test/context/support/AnnotationConfigContextLoaderTests.java +++ b/org.springframework.test/src/test/java/org/springframework/test/context/support/AnnotationConfigContextLoaderTests.java @@ -33,47 +33,47 @@ public class AnnotationConfigContextLoaderTests { @Test - public void generateDefaultConfigurationClassesForAnnotatedInnerClass() { - Class[] configClasses = contextLoader.generateDefaultConfigurationClasses(ContextConfigurationInnerClassTestCase.class); + public void detectDefaultConfigurationClassesForAnnotatedInnerClass() { + Class[] configClasses = contextLoader.detectDefaultConfigurationClasses(ContextConfigurationInnerClassTestCase.class); assertNotNull(configClasses); assertEquals("annotated static ContextConfiguration should be considered.", 1, configClasses.length); - configClasses = contextLoader.generateDefaultConfigurationClasses(AnnotatedFooConfigInnerClassTestCase.class); + configClasses = contextLoader.detectDefaultConfigurationClasses(AnnotatedFooConfigInnerClassTestCase.class); assertNotNull(configClasses); assertEquals("annotated static FooConfig should be considered.", 1, configClasses.length); } @Test - public void generateDefaultConfigurationClassesForMultipleAnnotatedInnerClasses() { - Class[] configClasses = contextLoader.generateDefaultConfigurationClasses(MultipleStaticConfigurationClassesTestCase.class); + public void detectDefaultConfigurationClassesForMultipleAnnotatedInnerClasses() { + Class[] configClasses = contextLoader.detectDefaultConfigurationClasses(MultipleStaticConfigurationClassesTestCase.class); assertNotNull(configClasses); assertEquals("multiple annotated static classes should be considered.", 2, configClasses.length); } @Test - public void generateDefaultConfigurationClassesForNonAnnotatedInnerClass() { - Class[] configClasses = contextLoader.generateDefaultConfigurationClasses(PlainVanillaFooConfigInnerClassTestCase.class); + public void detectDefaultConfigurationClassesForNonAnnotatedInnerClass() { + Class[] configClasses = contextLoader.detectDefaultConfigurationClasses(PlainVanillaFooConfigInnerClassTestCase.class); assertNotNull(configClasses); assertEquals("non-annotated static FooConfig should NOT be considered.", 0, configClasses.length); } @Test - public void generateDefaultConfigurationClassesForFinalAnnotatedInnerClass() { - Class[] configClasses = contextLoader.generateDefaultConfigurationClasses(FinalConfigInnerClassTestCase.class); + public void detectDefaultConfigurationClassesForFinalAnnotatedInnerClass() { + Class[] configClasses = contextLoader.detectDefaultConfigurationClasses(FinalConfigInnerClassTestCase.class); assertNotNull(configClasses); assertEquals("final annotated static Config should NOT be considered.", 0, configClasses.length); } @Test - public void generateDefaultConfigurationClassesForPrivateAnnotatedInnerClass() { - Class[] configClasses = contextLoader.generateDefaultConfigurationClasses(PrivateConfigInnerClassTestCase.class); + public void detectDefaultConfigurationClassesForPrivateAnnotatedInnerClass() { + Class[] configClasses = contextLoader.detectDefaultConfigurationClasses(PrivateConfigInnerClassTestCase.class); assertNotNull(configClasses); assertEquals("private annotated inner classes should NOT be considered.", 0, configClasses.length); } @Test - public void generateDefaultConfigurationClassesForNonStaticAnnotatedInnerClass() { - Class[] configClasses = contextLoader.generateDefaultConfigurationClasses(NonStaticConfigInnerClassesTestCase.class); + public void detectDefaultConfigurationClassesForNonStaticAnnotatedInnerClass() { + Class[] configClasses = contextLoader.detectDefaultConfigurationClasses(NonStaticConfigInnerClassesTestCase.class); assertNotNull(configClasses); assertEquals("non-static annotated inner classes should NOT be considered.", 0, configClasses.length); }