提交 72da569a 编写于 作者: S Sam Brannen

[SPR-8386][SPR-8387] Revised Javadoc in the TestContext framework regarding changes in 3.1.

上级 1c7cc172
......@@ -44,7 +44,7 @@ import java.lang.annotation.Target;
public @interface ActiveProfiles {
/**
* Alias for {@link #profiles() profiles}.
* Alias for {@link #profiles}.
*
* <p>This attribute may <strong>not</strong> be used in conjunction
* with {@link #profiles}, but it may be used <em>instead</em> of
......
......@@ -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}.
* <p>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.
* <p>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 <code>null</code>)
* @see #remove
*/
......
......@@ -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}.
*
* <p>This attribute may <strong>not</strong> 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}.
*
* <p>Check out the javadoc for
* <p>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 <code>locations</code> are configured. See the
* documentation for {@link #loader} for further details regarding default
* loaders.
*
* <p>This attribute may <strong>not</strong> 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}.
*
* <p>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.
*
* <p>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.
* <p>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.
*
* <p>This attribute may <strong>not</strong> be used in conjunction with
* {@link #locations} or {@link #value}.
......
......@@ -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.
*
* <p><b>Note</b>: 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.
* <p><b>Note</b>: 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.
*
* <p>Clients of a ContextLoader should call
* {@link #processLocations(Class,String...) processLocations()} prior to
......@@ -38,7 +39,6 @@ import org.springframework.context.ApplicationContext;
* <p>Spring provides the following out-of-the-box implementations:
* <ul>
* <li>{@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader}</li>
* <li>{@link org.springframework.test.context.support.AnnotationConfigContextLoader AnnotationConfigContextLoader}</li>
* <li>{@link org.springframework.test.context.support.GenericPropertiesContextLoader GenericPropertiesContextLoader}</li>
* </ul>
*
......@@ -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 {
* <p>Configuration locations are generally considered to be classpath
* resources by default.
* <p>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}.
* <p>Any ApplicationContext loaded by a ContextLoader <strong>must</strong>
* register a JVM shutdown hook for itself. Unless the context gets closed
* early, all context instances will be automatically closed on JVM
......
......@@ -19,7 +19,7 @@ package org.springframework.test.context;
import org.springframework.context.ApplicationContext;
/**
* <p>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.
*
* <p>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()}.
......
......@@ -108,7 +108,8 @@ public class TestContext extends AttributeAccessorSupport {
/**
* Load an <code>ApplicationContext</code> 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 {
......
......@@ -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
* <em>Template Method</em> based approach for {@link #processLocations processing}
* resource locations.
......@@ -190,6 +190,13 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* Determine whether or not <em>default</em> resource locations should be
* generated if the <code>locations</code> provided to
* {@link #processLocations()} are <code>null</code> or empty.
* <p>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 <em>default</em> configuration classes should be
* detected if the <code>classes</code> present in the
* {@link ContextConfigurationAttributes configuration attributes} supplied
* to {@link #processContextConfiguration()} are <code>null</code> or empty.
* <p>Can be overridden by subclasses to change the default behavior.
* @return always <code>true</code> by default
* @since 2.5
......
......@@ -68,18 +68,18 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader
* <li>Sets the <em>active bean definition profiles</em> from the supplied
* <code>MergedContextConfiguration</code> in the
* {@link org.springframework.core.env.Environment Environment} of the context.</li>
* <li>Calls {@link #prepareContext(GenericApplicationContext)} to
* prepare the context.</li>
* <li>Calls {@link #customizeBeanFactory(DefaultListableBeanFactory)} to
* allow for customizing the context's <code>DefaultListableBeanFactory</code>.</li>
* <li>Calls {@link #prepareContext()} to allow for customizing the context
* before bean definitions are loaded.</li>
* <li>Calls {@link #customizeBeanFactory()} to allow for customizing the
* context's <code>DefaultListableBeanFactory</code>.</li>
* <li>Delegates to {@link #loadBeanDefinitions()} to populate the context
* from the configuration locations or classes in the supplied
* <code>MergedContextConfiguration</code>.</li>
* <li>Delegates to {@link AnnotationConfigUtils} for
* {@link AnnotationConfigUtils#registerAnnotationConfigProcessors registering}
* annotation configuration processors.</li>
* <li>Calls {@link #customizeContext(GenericApplicationContext)} to allow
* for customizing the context before it is refreshed.</li>
* <li>Calls {@link #customizeContext()} to allow for customizing the context
* before it is refreshed.</li>
* <li>{@link ConfigurableApplicationContext#refresh Refreshes} the
* context and registers a JVM shutdown hook for it.</li>
* </ul>
......@@ -110,18 +110,18 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader
* <p>Implementation details:
* <ul>
* <li>Creates a {@link GenericApplicationContext} instance.</li>
* <li>Calls {@link #prepareContext(GenericApplicationContext)} to
* prepare the context.</li>
* <li>Calls {@link #customizeBeanFactory(DefaultListableBeanFactory)} to
* allow for customizing the context's <code>DefaultListableBeanFactory</code>.</li>
* <li>Calls {@link #prepareContext()} to allow for customizing the context
* before bean definitions are loaded.</li>
* <li>Calls {@link #customizeBeanFactory()} to allow for customizing the
* context's <code>DefaultListableBeanFactory</code>.</li>
* <li>Delegates to {@link #createBeanDefinitionReader()} to create a
* {@link BeanDefinitionReader} which is then used to populate the context
* from the specified config locations.</li>
* <li>Delegates to {@link AnnotationConfigUtils} for
* {@link AnnotationConfigUtils#registerAnnotationConfigProcessors registering}
* annotation configuration processors.</li>
* <li>Calls {@link #customizeContext(GenericApplicationContext)} to allow
* for customizing the context before it is refreshed.</li>
* <li>Calls {@link #customizeContext()} to allow for customizing the context
* before it is refreshed.</li>
* <li>{@link ConfigurableApplicationContext#refresh Refreshes} the
* context and registers a JVM shutdown hook for it.</li>
* </ul>
......
......@@ -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}.
* <p>If the configuration classes are <code>null</code> or empty and
* {@link #isGenerateDefaultLocations()} returns <code>true</code>, this
* <code>SmartContextLoader</code> will attempt to
* {@link #generateDefaultConfigurationClasses generate default configuration classes}.
* Otherwise, properties in the supplied configuration attributes will not
* be modified.
* <code>SmartContextLoader</code> 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.
* <p>The generated class array will contain all static inner classes of
* Detect the default configuration classes for the supplied test class.
* <p>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}.
* <p>The implementation of this method adheres to the contract defined in the
* {@link org.springframework.test.context.SmartContextLoader SmartContextLoader}
* SPI. Specifically, this method will <em>preemptively</em> verify that the
* generated default configuration classes exist <b>and</b> 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 <code>null</code>
*/
protected Class<?>[] generateDefaultConfigurationClasses(Class<?> declaringClass) {
protected Class<?>[] detectDefaultConfigurationClasses(Class<?> declaringClass) {
Assert.notNull(declaringClass, "Declaring class must not be null");
List<Class<?>> configClasses = new ArrayList<Class<?>>();
......
......@@ -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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册