Merge branch '5.1.x'

This commit is contained in:
Sam Brannen 2019-09-26 10:55:55 +02:00
commit f05b4625de
11 changed files with 193 additions and 174 deletions

View File

@ -34,8 +34,9 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Convenient adapter for programmatic registration of annotated bean classes. * Convenient adapter for programmatic registration of bean classes.
* This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying *
* <p>This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
* the same resolution of annotations but for explicitly registered classes only. * the same resolution of annotations but for explicitly registered classes only.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
@ -58,7 +59,7 @@ public class AnnotatedBeanDefinitionReader {
/** /**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry. * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
* If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext}, * <p>If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
* the {@link Environment} will be inherited, otherwise a new * the {@link Environment} will be inherited, otherwise a new
* {@link StandardEnvironment} will be created and used. * {@link StandardEnvironment} will be created and used.
* @param registry the {@code BeanFactory} to load bean definitions into, * @param registry the {@code BeanFactory} to load bean definitions into,
@ -71,8 +72,8 @@ public class AnnotatedBeanDefinitionReader {
} }
/** /**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry,
* the given {@link Environment}. * using the given {@link Environment}.
* @param registry the {@code BeanFactory} to load bean definitions into, * @param registry the {@code BeanFactory} to load bean definitions into,
* in the form of a {@code BeanDefinitionRegistry} * in the form of a {@code BeanDefinitionRegistry}
* @param environment the {@code Environment} to use when evaluating bean definition * @param environment the {@code Environment} to use when evaluating bean definition
@ -89,14 +90,14 @@ public class AnnotatedBeanDefinitionReader {
/** /**
* Return the BeanDefinitionRegistry that this scanner operates on. * Get the BeanDefinitionRegistry that this reader operates on.
*/ */
public final BeanDefinitionRegistry getRegistry() { public final BeanDefinitionRegistry getRegistry() {
return this.registry; return this.registry;
} }
/** /**
* Set the Environment to use when evaluating whether * Set the {@code Environment} to use when evaluating whether
* {@link Conditional @Conditional}-annotated component classes should be registered. * {@link Conditional @Conditional}-annotated component classes should be registered.
* <p>The default is a {@link StandardEnvironment}. * <p>The default is a {@link StandardEnvironment}.
* @see #registerBean(Class, String, Class...) * @see #registerBean(Class, String, Class...)
@ -106,7 +107,7 @@ public class AnnotatedBeanDefinitionReader {
} }
/** /**
* Set the BeanNameGenerator to use for detected bean classes. * Set the {@code BeanNameGenerator} to use for detected bean classes.
* <p>The default is a {@link AnnotationBeanNameGenerator}. * <p>The default is a {@link AnnotationBeanNameGenerator}.
*/ */
public void setBeanNameGenerator(@Nullable BeanNameGenerator beanNameGenerator) { public void setBeanNameGenerator(@Nullable BeanNameGenerator beanNameGenerator) {
@ -115,7 +116,7 @@ public class AnnotatedBeanDefinitionReader {
} }
/** /**
* Set the ScopeMetadataResolver to use for detected bean classes. * Set the {@code ScopeMetadataResolver} to use for registered component classes.
* <p>The default is an {@link AnnotationScopeMetadataResolver}. * <p>The default is an {@link AnnotationScopeMetadataResolver}.
*/ */
public void setScopeMetadataResolver(@Nullable ScopeMetadataResolver scopeMetadataResolver) { public void setScopeMetadataResolver(@Nullable ScopeMetadataResolver scopeMetadataResolver) {
@ -125,99 +126,99 @@ public class AnnotatedBeanDefinitionReader {
/** /**
* Register one or more annotated classes to be processed. * Register one or more component classes to be processed.
* <p>Calls to {@code register} are idempotent; adding the same * <p>Calls to {@code register} are idempotent; adding the same
* annotated class more than once has no additional effect. * component class more than once has no additional effect.
* @param annotatedClasses one or more annotated classes, * @param componentClasses one or more component classes,
* e.g. {@link Configuration @Configuration} classes * e.g. {@link Configuration @Configuration} classes
*/ */
public void register(Class<?>... annotatedClasses) { public void register(Class<?>... componentClasses) {
for (Class<?> annotatedClass : annotatedClasses) { for (Class<?> componentClass : componentClasses) {
registerBean(annotatedClass); registerBean(componentClass);
} }
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations. * class-declared annotations.
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
*/ */
public void registerBean(Class<?> annotatedClass) { public void registerBean(Class<?> beanClass) {
doRegisterBean(annotatedClass, null, null, null, null); doRegisterBean(beanClass, null, null, null, null);
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations. * class-declared annotations.
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
* @param name an explicit name for the bean * @param name an explicit name for the bean
* (or {@code null} for generating a default bean name) * (or {@code null} for generating a default bean name)
* @since 5.2 * @since 5.2
*/ */
public void registerBean(Class<?> annotatedClass, @Nullable String name) { public void registerBean(Class<?> beanClass, @Nullable String name) {
doRegisterBean(annotatedClass, name, null, null, null); doRegisterBean(beanClass, name, null, null, null);
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations. * class-declared annotations.
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
* @param qualifiers specific qualifier annotations to consider, * @param qualifiers specific qualifier annotations to consider,
* in addition to qualifiers at the bean class level * in addition to qualifiers at the bean class level
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) { public void registerBean(Class<?> beanClass, Class<? extends Annotation>... qualifiers) {
doRegisterBean(annotatedClass, null, qualifiers, null, null); doRegisterBean(beanClass, null, qualifiers, null, null);
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations. * class-declared annotations.
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
* @param name an explicit name for the bean * @param name an explicit name for the bean
* (or {@code null} for generating a default bean name) * (or {@code null} for generating a default bean name)
* @param qualifiers specific qualifier annotations to consider, * @param qualifiers specific qualifier annotations to consider,
* in addition to qualifiers at the bean class level * in addition to qualifiers at the bean class level
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, @Nullable String name, public void registerBean(Class<?> beanClass, @Nullable String name,
Class<? extends Annotation>... qualifiers) { Class<? extends Annotation>... qualifiers) {
doRegisterBean(annotatedClass, name, qualifiers, null, null); doRegisterBean(beanClass, name, qualifiers, null, null);
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations, using the given supplier for obtaining a new * class-declared annotations, using the given supplier for obtaining a new
* instance (possibly declared as a lambda expression or method reference). * instance (possibly declared as a lambda expression or method reference).
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
* @param supplier a callback for creating an instance of the bean * @param supplier a callback for creating an instance of the bean
* (may be {@code null}) * (may be {@code null})
* @since 5.0 * @since 5.0
*/ */
public <T> void registerBean(Class<T> annotatedClass, @Nullable Supplier<T> supplier) { public <T> void registerBean(Class<T> beanClass, @Nullable Supplier<T> supplier) {
doRegisterBean(annotatedClass, null, null, supplier, null); doRegisterBean(beanClass, null, null, supplier, null);
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations, using the given supplier for obtaining a new * class-declared annotations, using the given supplier for obtaining a new
* instance (possibly declared as a lambda expression or method reference). * instance (possibly declared as a lambda expression or method reference).
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
* @param name an explicit name for the bean * @param name an explicit name for the bean
* (or {@code null} for generating a default bean name) * (or {@code null} for generating a default bean name)
* @param supplier a callback for creating an instance of the bean * @param supplier a callback for creating an instance of the bean
* (may be {@code null}) * (may be {@code null})
* @since 5.0 * @since 5.0
*/ */
public <T> void registerBean(Class<T> annotatedClass, @Nullable String name, @Nullable Supplier<T> supplier) { public <T> void registerBean(Class<T> beanClass, @Nullable String name, @Nullable Supplier<T> supplier) {
doRegisterBean(annotatedClass, name, null, supplier, null); doRegisterBean(beanClass, name, null, supplier, null);
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations. * class-declared annotations.
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
* @param name an explicit name for the bean * @param name an explicit name for the bean
* (or {@code null} for generating a default bean name) * (or {@code null} for generating a default bean name)
* @param supplier a callback for creating an instance of the bean * @param supplier a callback for creating an instance of the bean
@ -226,16 +227,16 @@ public class AnnotatedBeanDefinitionReader {
* {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.2 * @since 5.2
*/ */
public <T> void registerBean(Class<T> annotatedClass, @Nullable String name, @Nullable Supplier<T> supplier, public <T> void registerBean(Class<T> beanClass, @Nullable String name, @Nullable Supplier<T> supplier,
BeanDefinitionCustomizer... customizers) { BeanDefinitionCustomizer... customizers) {
doRegisterBean(annotatedClass, name, null, supplier, customizers); doRegisterBean(beanClass, name, null, supplier, customizers);
} }
/** /**
* Register a bean from the given bean class, deriving its metadata from * Register a bean from the given bean class, deriving its metadata from
* class-declared annotations. * class-declared annotations.
* @param annotatedClass the class of the bean * @param beanClass the class of the bean
* @param name an explicit name for the bean * @param name an explicit name for the bean
* @param supplier a callback for creating an instance of the bean * @param supplier a callback for creating an instance of the bean
* (may be {@code null}) * (may be {@code null})
@ -245,11 +246,11 @@ public class AnnotatedBeanDefinitionReader {
* {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0 * @since 5.0
*/ */
private <T> void doRegisterBean(Class<T> annotatedClass, @Nullable String name, private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) { @Nullable BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return; return;
} }

View File

@ -27,19 +27,20 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Standalone application context, accepting annotated classes as input - in particular * Standalone application context, accepting <em>component classes</em> as input &mdash;
* {@link Configuration @Configuration}-annotated classes, but also plain * in particular {@link Configuration @Configuration}-annotated classes, but also plain
* {@link org.springframework.stereotype.Component @Component} types and JSR-330 compliant * {@link org.springframework.stereotype.Component @Component} types and JSR-330 compliant
* classes using {@code javax.inject} annotations. Allows for registering classes one by * classes using {@code javax.inject} annotations.
* one using {@link #register(Class...)} as well as for classpath scanning using
* {@link #scan(String...)}.
* *
* <p>In case of multiple {@code @Configuration} classes, @{@link Bean} methods defined in * <p>Allows for registering classes one by one using {@link #register(Class...)}
* later classes will override those defined in earlier classes. This can be leveraged to * as well as for classpath scanning using {@link #scan(String...)}.
* deliberately override certain bean definitions via an extra {@code @Configuration}
* class.
* *
* <p>See @{@link Configuration}'s javadoc for usage examples. * <p>In case of multiple {@code @Configuration} classes, {@link Bean @Bean} methods
* defined in later classes will override those defined in earlier classes. This can
* be leveraged to deliberately override certain bean definitions via an extra
* {@code @Configuration} class.
*
* <p>See {@link Configuration @Configuration}'s javadoc for usage examples.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Chris Beams * @author Chris Beams
@ -78,20 +79,21 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
/** /**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions * Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context. * from the given component classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes, * @param componentClasses one or more component classes &mdash; for example,
* e.g. {@link Configuration @Configuration} classes * {@link Configuration @Configuration} classes
*/ */
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this(); this();
register(annotatedClasses); register(componentClasses);
refresh(); refresh();
} }
/** /**
* Create a new AnnotationConfigApplicationContext, scanning for bean definitions * Create a new AnnotationConfigApplicationContext, scanning for components
* in the given packages and automatically refreshing the context. * in the given packages, registering bean definitions for those components,
* @param basePackages the packages to check for annotated classes * and automatically refreshing the context.
* @param basePackages the packages to scan for component classes
*/ */
public AnnotationConfigApplicationContext(String... basePackages) { public AnnotationConfigApplicationContext(String... basePackages) {
this(); this();
@ -101,7 +103,7 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
/** /**
* Propagates the given custom {@code Environment} to the underlying * Propagate the given custom {@code Environment} to the underlying
* {@link AnnotatedBeanDefinitionReader} and {@link ClassPathBeanDefinitionScanner}. * {@link AnnotatedBeanDefinitionReader} and {@link ClassPathBeanDefinitionScanner}.
*/ */
@Override @Override
@ -128,7 +130,7 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
} }
/** /**
* Set the {@link ScopeMetadataResolver} to use for detected bean classes. * Set the {@link ScopeMetadataResolver} to use for registered component classes.
* <p>The default is an {@link AnnotationScopeMetadataResolver}. * <p>The default is an {@link AnnotationScopeMetadataResolver}.
* <p>Any call to this method must occur prior to calls to {@link #register(Class...)} * <p>Any call to this method must occur prior to calls to {@link #register(Class...)}
* and/or {@link #scan(String...)}. * and/or {@link #scan(String...)}.
@ -144,25 +146,25 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
//--------------------------------------------------------------------- //---------------------------------------------------------------------
/** /**
* Register one or more annotated classes to be processed. * Register one or more component classes to be processed.
* <p>Note that {@link #refresh()} must be called in order for the context * <p>Note that {@link #refresh()} must be called in order for the context
* to fully process the new classes. * to fully process the new classes.
* @param annotatedClasses one or more annotated classes, * @param componentClasses one or more component classes &mdash; for example,
* e.g. {@link Configuration @Configuration} classes * {@link Configuration @Configuration} classes
* @see #scan(String...) * @see #scan(String...)
* @see #refresh() * @see #refresh()
*/ */
@Override @Override
public void register(Class<?>... annotatedClasses) { public void register(Class<?>... componentClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified"); Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(annotatedClasses); this.reader.register(componentClasses);
} }
/** /**
* Perform a scan within the specified base packages. * Perform a scan within the specified base packages.
* <p>Note that {@link #refresh()} must be called in order for the context * <p>Note that {@link #refresh()} must be called in order for the context
* to fully process the new classes. * to fully process the new classes.
* @param basePackages the packages to check for annotated classes * @param basePackages the packages to scan for component classes
* @see #register(Class...) * @see #register(Class...)
* @see #refresh() * @see #refresh()
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,17 +26,17 @@ package org.springframework.context.annotation;
public interface AnnotationConfigRegistry { public interface AnnotationConfigRegistry {
/** /**
* Register one or more annotated classes to be processed. * Register one or more component classes to be processed.
* <p>Calls to {@code register} are idempotent; adding the same * <p>Calls to {@code register} are idempotent; adding the same
* annotated class more than once has no additional effect. * component class more than once has no additional effect.
* @param annotatedClasses one or more annotated classes, * @param componentClasses one or more component classes,
* e.g. {@link Configuration @Configuration} classes * e.g. {@link Configuration @Configuration} classes
*/ */
void register(Class<?>... annotatedClasses); void register(Class<?>... componentClasses);
/** /**
* Perform a scan within the specified base packages. * Perform a scan within the specified base packages.
* @param basePackages the packages to check for annotated classes * @param basePackages the packages to scan for component classes
*/ */
void scan(String... basePackages); void scan(String... basePackages);

View File

@ -352,7 +352,8 @@ import org.springframework.stereotype.Component;
* *
* <p>The Spring <em>TestContext framework</em> available in the {@code spring-test} module * <p>The Spring <em>TestContext framework</em> available in the {@code spring-test} module
* provides the {@code @ContextConfiguration} annotation which can accept an array of * provides the {@code @ContextConfiguration} annotation which can accept an array of
* {@code @Configuration} {@code Class} objects: * <em>component class</em> references &mdash; typically {@code @Configuration} or
* {@code @Component} classes.
* *
* <pre class="code"> * <pre class="code">
* &#064;RunWith(SpringRunner.class) * &#064;RunWith(SpringRunner.class)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,7 +23,8 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* Indicates one or more {@link Configuration @Configuration} classes to import. * Indicates one or more <em>component classes</em> to import &mdash; typically
* {@link Configuration @Configuration} classes.
* *
* <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML. * <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.
* Allows for importing {@code @Configuration} classes, {@link ImportSelector} and * Allows for importing {@code @Configuration} classes, {@link ImportSelector} and
@ -55,8 +56,8 @@ import java.lang.annotation.Target;
public @interface Import { public @interface Import {
/** /**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar} * {@link Configuration @Configuration}, {@link ImportSelector},
* or regular component classes to import. * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/ */
Class<?>[] value(); Class<?>[] value();

View File

@ -41,15 +41,15 @@ import org.springframework.core.annotation.AliasFor;
* <em>and</em> class-based resources simultaneously. Consequently * <em>and</em> class-based resources simultaneously. Consequently
* {@code @ContextConfiguration} can be used to declare either path-based resource * {@code @ContextConfiguration} can be used to declare either path-based resource
* locations (via the {@link #locations} or {@link #value} attribute) <em>or</em> * locations (via the {@link #locations} or {@link #value} attribute) <em>or</em>
* annotated classes (via the {@link #classes} attribute). Note, however, that most * component classes (via the {@link #classes} attribute). Note, however, that most
* implementations of {@link SmartContextLoader} only support a single resource type. As * implementations of {@link SmartContextLoader} only support a single resource type. As
* of Spring 4.1, path-based resource locations may be either XML configuration files or * of Spring 4.1, path-based resource locations may be either XML configuration files or
* Groovy scripts (if Groovy is on the classpath). Of course, third-party frameworks may * Groovy scripts (if Groovy is on the classpath). Of course, third-party frameworks may
* choose to support additional types of path-based resources. * choose to support additional types of path-based resources.
* *
* <h3>Annotated Classes</h3> * <h3>Component Classes</h3>
* *
* <p>The term <em>annotated class</em> can refer to any of the following. * <p>The term <em>component class</em> can refer to any of the following.
* *
* <ul> * <ul>
* <li>A class annotated with {@link org.springframework.context.annotation.Configuration @Configuration}</li> * <li>A class annotated with {@link org.springframework.context.annotation.Configuration @Configuration}</li>
@ -58,15 +58,22 @@ import org.springframework.core.annotation.AliasFor;
* {@link org.springframework.stereotype.Service @Service}, * {@link org.springframework.stereotype.Service @Service},
* {@link org.springframework.stereotype.Repository @Repository}, etc.)</li> * {@link org.springframework.stereotype.Repository @Repository}, etc.)</li>
* <li>A JSR-330 compliant class that is annotated with {@code javax.inject} annotations</li> * <li>A JSR-330 compliant class that is annotated with {@code javax.inject} annotations</li>
* <li>Any other class that contains {@link org.springframework.context.annotation.Bean @Bean}-methods</li> * <li>Any class that contains {@link org.springframework.context.annotation.Bean @Bean}-methods</li>
* <li>Any other class that is intended to be registered as a Spring component (i.e., a Spring bean
* in the {@code ApplicationContext}), potentially taking advantage of automatic autowiring of a
* single constructor without the use of Spring annotations</li>
* </ul> * </ul>
* *
* A bean will be registered in the {@code ApplicationContext} for each component
* class, and such beans can therefore be injected into other beans or into the
* instance of the test class.
*
* <p>Consult the Javadoc for {@link org.springframework.context.annotation.Configuration @Configuration} * <p>Consult the Javadoc for {@link org.springframework.context.annotation.Configuration @Configuration}
* and {@link org.springframework.context.annotation.Bean @Bean} for further * and {@link org.springframework.context.annotation.Bean @Bean} for further
* information regarding the configuration and semantics of <em>annotated classes</em>. * information regarding the configuration and semantics of <em>component classes</em>.
* *
* <p>As of Spring Framework 4.0, this annotation may be used as a <em>meta-annotation</em> * <p>This annotation may be used as a <em>meta-annotation</em> to create custom
* to create custom <em>composed annotations</em>. * <em>composed annotations</em>.
* *
* @author Sam Brannen * @author Sam Brannen
* @since 2.5 * @since 2.5
@ -124,13 +131,13 @@ public @interface ContextConfiguration {
String[] locations() default {}; String[] locations() default {};
/** /**
* The <em>annotated classes</em> to use for loading an * The <em>component classes</em> to use for loading an
* {@link org.springframework.context.ApplicationContext ApplicationContext}. * {@link org.springframework.context.ApplicationContext ApplicationContext}.
* <p>Check out the javadoc for * <p>Check out the javadoc for
* {@link org.springframework.test.context.support.AnnotationConfigContextLoader#detectDefaultConfigurationClasses * {@link org.springframework.test.context.support.AnnotationConfigContextLoader#detectDefaultConfigurationClasses
* AnnotationConfigContextLoader.detectDefaultConfigurationClasses()} for details * AnnotationConfigContextLoader.detectDefaultConfigurationClasses()} for details
* on how default configuration classes will be detected if no * on how default configuration classes will be detected if no
* <em>annotated classes</em> are specified. See the documentation for * <em>component classes</em> are specified. See the documentation for
* {@link #loader} for further details regarding default loaders. * {@link #loader} for further details regarding default loaders.
* @since 3.1 * @since 3.1
* @see org.springframework.context.annotation.Configuration * @see org.springframework.context.annotation.Configuration
@ -158,19 +165,20 @@ public @interface ContextConfiguration {
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {}; Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
/** /**
* Whether or not {@link #locations resource locations} or <em>annotated * Whether or not {@linkplain #locations resource locations} or
* classes</em> from test superclasses should be <em>inherited</em>. * {@linkplain #classes <em>component classes</em>} from test superclasses
* <p>The default value is {@code true}. This means that an annotated * should be <em>inherited</em>.
* class will <em>inherit</em> the resource locations or annotated classes * <p>The default value is {@code true}. This means that an annotated test
* class will <em>inherit</em> the resource locations or component classes
* defined by test superclasses. Specifically, the resource locations or * defined by test superclasses. Specifically, the resource locations or
* annotated classes for a given test class will be appended to the list of * component classes for a given test class will be appended to the list of
* resource locations or annotated classes defined by test superclasses. * resource locations or component classes defined by test superclasses.
* Thus, subclasses have the option of <em>extending</em> the list of resource * Thus, subclasses have the option of <em>extending</em> the list of resource
* locations or annotated classes. * locations or component classes.
* <p>If {@code inheritLocations} is set to {@code false}, the * <p>If {@code inheritLocations} is set to {@code false}, the
* resource locations or annotated classes for the annotated class * resource locations or component classes for the annotated test class
* will <em>shadow</em> and effectively replace any resource locations * will <em>shadow</em> and effectively replace any resource locations
* or annotated classes defined by superclasses. * or component classes defined by superclasses.
* <p>In the following example that uses path-based resource locations, the * <p>In the following example that uses path-based resource locations, the
* {@link org.springframework.context.ApplicationContext ApplicationContext} * {@link org.springframework.context.ApplicationContext ApplicationContext}
* for {@code ExtendedTest} will be loaded from * for {@code ExtendedTest} will be loaded from
@ -189,8 +197,7 @@ public @interface ContextConfiguration {
* // ... * // ...
* } * }
* </pre> * </pre>
* <p>Similarly, in the following example that uses annotated * <p>Similarly, in the following example that uses component classes, the
* classes, the
* {@link org.springframework.context.ApplicationContext ApplicationContext} * {@link org.springframework.context.ApplicationContext ApplicationContext}
* for {@code ExtendedTest} will be loaded from the * for {@code ExtendedTest} will be loaded from the
* {@code BaseConfig} <strong>and</strong> {@code ExtendedConfig} * {@code BaseConfig} <strong>and</strong> {@code ExtendedConfig}
@ -215,15 +222,15 @@ public @interface ContextConfiguration {
/** /**
* Whether or not {@linkplain #initializers context initializers} from test * Whether or not {@linkplain #initializers context initializers} from test
* superclasses should be <em>inherited</em>. * superclasses should be <em>inherited</em>.
* <p>The default value is {@code true}. This means that an annotated * <p>The default value is {@code true}. This means that an annotated test
* class will <em>inherit</em> the application context initializers defined * class will <em>inherit</em> the application context initializers defined
* by test superclasses. Specifically, the initializers for a given test * by test superclasses. Specifically, the initializers for a given test
* class will be added to the set of initializers defined by test * class will be added to the set of initializers defined by test
* superclasses. Thus, subclasses have the option of <em>extending</em> the * superclasses. Thus, subclasses have the option of <em>extending</em> the
* set of initializers. * set of initializers.
* <p>If {@code inheritInitializers} is set to {@code false}, the * <p>If {@code inheritInitializers} is set to {@code false}, the initializers
* initializers for the annotated class will <em>shadow</em> and effectively * for the annotated test class will <em>shadow</em> and effectively replace
* replace any initializers defined by superclasses. * any initializers defined by superclasses.
* <p>In the following example, the * <p>In the following example, the
* {@link org.springframework.context.ApplicationContext ApplicationContext} * {@link org.springframework.context.ApplicationContext ApplicationContext}
* for {@code ExtendedTest} will be initialized using * for {@code ExtendedTest} will be initialized using
@ -252,9 +259,9 @@ public @interface ContextConfiguration {
* for loading an {@link org.springframework.context.ApplicationContext * for loading an {@link org.springframework.context.ApplicationContext
* ApplicationContext}. * ApplicationContext}.
* <p>If not specified, the loader will be inherited from the first superclass * <p>If not specified, the loader will be inherited from the first superclass
* that is annotated with {@code @ContextConfiguration} and specifies an * that is annotated or meta-annotated with {@code @ContextConfiguration} and
* explicit loader. If no class in the hierarchy specifies an explicit * specifies an explicit loader. If no class in the hierarchy specifies an
* loader, a default loader will be used instead. * explicit loader, a default loader will be used instead.
* <p>The default concrete implementation chosen at runtime will be either * <p>The default concrete implementation chosen at runtime will be either
* {@link org.springframework.test.context.support.DelegatingSmartContextLoader * {@link org.springframework.test.context.support.DelegatingSmartContextLoader
* DelegatingSmartContextLoader} or * DelegatingSmartContextLoader} or

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -28,13 +28,13 @@ import org.springframework.util.ObjectUtils;
/** /**
* Concrete implementation of {@link AbstractGenericContextLoader} that loads * Concrete implementation of {@link AbstractGenericContextLoader} that loads
* bean definitions from annotated classes. * bean definitions from component classes.
* *
* <p>See the Javadoc for * <p>See the Javadoc for
* {@link org.springframework.test.context.ContextConfiguration @ContextConfiguration} * {@link org.springframework.test.context.ContextConfiguration @ContextConfiguration}
* for a definition of <em>annotated class</em>. * for a definition of <em>component class</em>.
* *
* <p>Note: {@code AnnotationConfigContextLoader} supports <em>annotated classes</em> * <p>Note: {@code AnnotationConfigContextLoader} supports <em>component classes</em>
* rather than the String-based resource locations defined by the legacy * rather than the String-based resource locations defined by the legacy
* {@link org.springframework.test.context.ContextLoader ContextLoader} API. Thus, * {@link org.springframework.test.context.ContextLoader ContextLoader} API. Thus,
* although {@code AnnotationConfigContextLoader} extends * although {@code AnnotationConfigContextLoader} extends
@ -61,8 +61,8 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader
// SmartContextLoader // SmartContextLoader
/** /**
* Process <em>annotated classes</em> in the supplied {@link ContextConfigurationAttributes}. * Process <em>component classes</em> in the supplied {@link ContextConfigurationAttributes}.
* <p>If the <em>annotated classes</em> are {@code null} or empty and * <p>If the <em>component classes</em> are {@code null} or empty and
* {@link #isGenerateDefaultLocations()} returns {@code true}, this * {@link #isGenerateDefaultLocations()} returns {@code true}, this
* {@code SmartContextLoader} will attempt to {@link * {@code SmartContextLoader} will attempt to {@link
* #detectDefaultConfigurationClasses detect default configuration classes}. * #detectDefaultConfigurationClasses detect default configuration classes}.
@ -167,23 +167,23 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader
/** /**
* Register classes in the supplied {@link GenericApplicationContext context} * Register classes in the supplied {@link GenericApplicationContext context}
* from the classes in the supplied {@link MergedContextConfiguration}. * from the classes in the supplied {@link MergedContextConfiguration}.
* <p>Each class must represent an <em>annotated class</em>. An * <p>Each class must represent a <em>component class</em>. An
* {@link AnnotatedBeanDefinitionReader} is used to register the appropriate * {@link AnnotatedBeanDefinitionReader} is used to register the appropriate
* bean definitions. * bean definitions.
* <p>Note that this method does not call {@link #createBeanDefinitionReader} * <p>Note that this method does not call {@link #createBeanDefinitionReader}
* since {@code AnnotatedBeanDefinitionReader} is not an instance of * since {@code AnnotatedBeanDefinitionReader} is not an instance of
* {@link BeanDefinitionReader}. * {@link BeanDefinitionReader}.
* @param context the context in which the annotated classes should be registered * @param context the context in which the component classes should be registered
* @param mergedConfig the merged configuration from which the classes should be retrieved * @param mergedConfig the merged configuration from which the classes should be retrieved
* @see AbstractGenericContextLoader#loadBeanDefinitions * @see AbstractGenericContextLoader#loadBeanDefinitions
*/ */
@Override @Override
protected void loadBeanDefinitions(GenericApplicationContext context, MergedContextConfiguration mergedConfig) { protected void loadBeanDefinitions(GenericApplicationContext context, MergedContextConfiguration mergedConfig) {
Class<?>[] annotatedClasses = mergedConfig.getClasses(); Class<?>[] componentClasses = mergedConfig.getClasses();
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Registering annotated classes: " + ObjectUtils.nullSafeToString(annotatedClasses)); logger.debug("Registering component classes: " + ObjectUtils.nullSafeToString(componentClasses));
} }
new AnnotatedBeanDefinitionReader(context).register(annotatedClasses); new AnnotatedBeanDefinitionReader(context).register(componentClasses);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,7 +32,7 @@ import org.springframework.util.ClassUtils;
/** /**
* Utility methods for {@link SmartContextLoader SmartContextLoaders} that deal * Utility methods for {@link SmartContextLoader SmartContextLoaders} that deal
* with annotated classes (e.g., {@link Configuration @Configuration} classes). * with component classes (e.g., {@link Configuration @Configuration} classes).
* *
* @author Sam Brannen * @author Sam Brannen
* @since 3.2 * @since 3.2

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,12 +35,13 @@ import org.springframework.web.context.ContextLoader;
/** /**
* {@link org.springframework.web.context.WebApplicationContext WebApplicationContext} * {@link org.springframework.web.context.WebApplicationContext WebApplicationContext}
* implementation which accepts annotated classes as input - in particular * implementation which accepts <em>component classes</em> as input &mdash; in particular
* {@link org.springframework.context.annotation.Configuration @Configuration}-annotated * {@link org.springframework.context.annotation.Configuration @Configuration}-annotated
* classes, but also plain {@link org.springframework.stereotype.Component @Component} * classes, but also plain {@link org.springframework.stereotype.Component @Component}
* classes and JSR-330 compliant classes using {@code javax.inject} annotations. Allows * classes and JSR-330 compliant classes using {@code javax.inject} annotations.
* for registering classes one by one (specifying class names as config location) as well *
* as for classpath scanning (specifying base packages as config location). * <p>Allows for registering classes one by one (specifying class names as config
* location) as well as for classpath scanning (specifying base packages as config location).
* *
* <p>This is essentially the equivalent of * <p>This is essentially the equivalent of
* {@link org.springframework.context.annotation.AnnotationConfigApplicationContext * {@link org.springframework.context.annotation.AnnotationConfigApplicationContext
@ -53,7 +54,7 @@ import org.springframework.web.context.ContextLoader;
* *
* <p>As of Spring 3.1, this class may also be directly instantiated and injected into * <p>As of Spring 3.1, this class may also be directly instantiated and injected into
* Spring's {@code DispatcherServlet} or {@code ContextLoaderListener} when using the * Spring's {@code DispatcherServlet} or {@code ContextLoaderListener} when using the
* new {@link org.springframework.web.WebApplicationInitializer WebApplicationInitializer} * {@link org.springframework.web.WebApplicationInitializer WebApplicationInitializer}
* code-based alternative to {@code web.xml}. See its Javadoc for details and usage examples. * code-based alternative to {@code web.xml}. See its Javadoc for details and usage examples.
* *
* <p>Unlike {@link XmlWebApplicationContext}, no default configuration class locations * <p>Unlike {@link XmlWebApplicationContext}, no default configuration class locations
@ -74,7 +75,8 @@ import org.springframework.web.context.ContextLoader;
* *
* <p>Note: In case of multiple {@code @Configuration} classes, later {@code @Bean} * <p>Note: In case of multiple {@code @Configuration} classes, later {@code @Bean}
* definitions will override ones defined in earlier loaded files. This can be leveraged * definitions will override ones defined in earlier loaded files. This can be leveraged
* to deliberately override certain bean definitions via an extra Configuration class. * to deliberately override certain bean definitions via an extra {@code @Configuration}
* class.
* *
* @author Chris Beams * @author Chris Beams
* @author Juergen Hoeller * @author Juergen Hoeller
@ -90,7 +92,7 @@ public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWe
@Nullable @Nullable
private ScopeMetadataResolver scopeMetadataResolver; private ScopeMetadataResolver scopeMetadataResolver;
private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>(); private final Set<Class<?>> componentClasses = new LinkedHashSet<>();
private final Set<String> basePackages = new LinkedHashSet<>(); private final Set<String> basePackages = new LinkedHashSet<>();
@ -137,10 +139,10 @@ public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWe
/** /**
* Register one or more annotated classes to be processed. * Register one or more component classes to be processed.
* <p>Note that {@link #refresh()} must be called in order for the context * <p>Note that {@link #refresh()} must be called in order for the context
* to fully process the new classes. * to fully process the new classes.
* @param annotatedClasses one or more annotated classes, * @param componentClasses one or more component classes,
* e.g. {@link org.springframework.context.annotation.Configuration @Configuration} classes * e.g. {@link org.springframework.context.annotation.Configuration @Configuration} classes
* @see #scan(String...) * @see #scan(String...)
* @see #loadBeanDefinitions(DefaultListableBeanFactory) * @see #loadBeanDefinitions(DefaultListableBeanFactory)
@ -148,16 +150,16 @@ public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWe
* @see #refresh() * @see #refresh()
*/ */
@Override @Override
public void register(Class<?>... annotatedClasses) { public void register(Class<?>... componentClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified"); Assert.notEmpty(componentClasses, "At least one component class must be specified");
Collections.addAll(this.annotatedClasses, annotatedClasses); Collections.addAll(this.componentClasses, componentClasses);
} }
/** /**
* Perform a scan within the specified base packages. * Perform a scan within the specified base packages.
* <p>Note that {@link #refresh()} must be called in order for the context * <p>Note that {@link #refresh()} must be called in order for the context
* to fully process the new classes. * to fully process the new classes.
* @param basePackages the packages to check for annotated classes * @param basePackages the packages to check for component classes
* @see #loadBeanDefinitions(DefaultListableBeanFactory) * @see #loadBeanDefinitions(DefaultListableBeanFactory)
* @see #register(Class...) * @see #register(Class...)
* @see #setConfigLocation(String) * @see #setConfigLocation(String)
@ -178,7 +180,7 @@ public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWe
* {@link #setConfigLocations(String[])}, attempt first to load each location as a * {@link #setConfigLocations(String[])}, attempt first to load each location as a
* class, registering a {@code BeanDefinition} if class loading is successful, * class, registering a {@code BeanDefinition} if class loading is successful,
* and if class loading fails (i.e. a {@code ClassNotFoundException} is raised), * and if class loading fails (i.e. a {@code ClassNotFoundException} is raised),
* assume the value is a package and attempt to scan it for annotated classes. * assume the value is a package and attempt to scan it for component classes.
* <p>Enables the default set of annotation configuration post processors, such that * <p>Enables the default set of annotation configuration post processors, such that
* {@code @Autowired}, {@code @Required}, and associated annotations can be used. * {@code @Autowired}, {@code @Required}, and associated annotations can be used.
* <p>Configuration class bean definitions are registered with generated bean * <p>Configuration class bean definitions are registered with generated bean
@ -210,12 +212,12 @@ public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWe
scanner.setScopeMetadataResolver(scopeMetadataResolver); scanner.setScopeMetadataResolver(scopeMetadataResolver);
} }
if (!this.annotatedClasses.isEmpty()) { if (!this.componentClasses.isEmpty()) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Registering annotated classes: [" + logger.debug("Registering component classes: [" +
StringUtils.collectionToCommaDelimitedString(this.annotatedClasses) + "]"); StringUtils.collectionToCommaDelimitedString(this.componentClasses) + "]");
} }
reader.register(ClassUtils.toClassArray(this.annotatedClasses)); reader.register(ClassUtils.toClassArray(this.componentClasses));
} }
if (!this.basePackages.isEmpty()) { if (!this.basePackages.isEmpty()) {
@ -243,7 +245,7 @@ public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWe
} }
int count = scanner.scan(configLocation); int count = scanner.scan(configLocation);
if (count == 0 && logger.isDebugEnabled()) { if (count == 0 && logger.isDebugEnabled()) {
logger.debug("No annotated classes found for specified class/package [" + configLocation + "]"); logger.debug("No component classes found for specified class/package [" + configLocation + "]");
} }
} }
} }

View File

@ -8743,7 +8743,7 @@ This approach simplifies container instantiation, as only one class needs to be
with, rather than requiring you to remember a potentially large number of with, rather than requiring you to remember a potentially large number of
`@Configuration` classes during construction. `@Configuration` classes during construction.
TIP: As of Spring Framework 4.2, `@Import` also supports references regular component TIP: As of Spring Framework 4.2, `@Import` also supports references to regular component
classes, analogous to the `AnnotationConfigApplicationContext.register` method. classes, analogous to the `AnnotationConfigApplicationContext.register` method.
This is particularly useful if you want to avoid component scanning, by using a few This is particularly useful if you want to avoid component scanning, by using a few
configuration classes as entry points to explicitly define all your components. configuration classes as entry points to explicitly define all your components.

View File

@ -258,7 +258,7 @@ load the mapping files, and incurring that cost before running every test in eve
fixture leads to slower overall test runs that reduce developer productivity. fixture leads to slower overall test runs that reduce developer productivity.
Test classes typically declare either an array of resource locations for XML or Groovy Test classes typically declare either an array of resource locations for XML or Groovy
configuration metadata -- often in the classpath -- or an array of annotated classes that configuration metadata -- often in the classpath -- or an array of component classes that
is used to configure the application. These locations or classes are the same as or is used to configure the application. These locations or classes are the same as or
similar to those specified in `web.xml` or other configuration files for production similar to those specified in `web.xml` or other configuration files for production
deployments. deployments.
@ -436,12 +436,13 @@ specify a custom `TestContextBootstrapper`. See the section on
`@ContextConfiguration` defines class-level metadata that is used to determine how to `@ContextConfiguration` defines class-level metadata that is used to determine how to
load and configure an `ApplicationContext` for integration tests. Specifically, load and configure an `ApplicationContext` for integration tests. Specifically,
`@ContextConfiguration` declares the application context resource `locations` or the `@ContextConfiguration` declares the application context resource `locations` or the
annotated `classes` used to load the context. component `classes` used to load the context.
Resource locations are typically XML configuration files or Groovy scripts located in the Resource locations are typically XML configuration files or Groovy scripts located in the
classpath, while annotated classes are typically `@Configuration` classes. However, classpath, while component classes are typically `@Configuration` classes. However,
resource locations can also refer to files and scripts in the file system, and annotated resource locations can also refer to files and scripts in the file system, and component
classes can be component classes, and so on. classes can be `@Component` classes, `@Service` classes, and so on. See
<<testcontext-ctx-management-javaconfig-component-classes>> for further details.
The following example shows a `@ContextConfiguration` annotation that refers to an XML The following example shows a `@ContextConfiguration` annotation that refers to an XML
file: file:
@ -490,7 +491,7 @@ The following example shows a `@ContextConfiguration` annotation that refers to
<1> Referring to a class. <1> Referring to a class.
As an alternative or in addition to declaring resource locations or annotated classes, As an alternative or in addition to declaring resource locations or component classes,
you can use `@ContextConfiguration` to declare `ApplicationContextInitializer` classes. you can use `@ContextConfiguration` to declare `ApplicationContextInitializer` classes.
The following example shows such a case: The following example shows such a case:
@ -517,7 +518,7 @@ The following example shows such a case:
You can optionally use `@ContextConfiguration` to declare the `ContextLoader` strategy as You can optionally use `@ContextConfiguration` to declare the `ContextLoader` strategy as
well. Note, however, that you typically do not need to explicitly configure the loader, well. Note, however, that you typically do not need to explicitly configure the loader,
since the default loader supports `initializers` and either resource `locations` or since the default loader supports `initializers` and either resource `locations` or
annotated `classes`. component `classes`.
The following example uses both a location and a loader: The following example uses both a location and a loader:
@ -1633,7 +1634,7 @@ The following annotations are supported only when used in conjunction with the
`@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` from `@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` from
the Spring TestContext Framework. It can be used at the class level as a drop-in the Spring TestContext Framework. It can be used at the class level as a drop-in
replacement for `@ContextConfiguration`. With regard to configuration options, the only replacement for `@ContextConfiguration`. With regard to configuration options, the only
difference between `@ContextConfiguration` and `@SpringJUnitConfig` is that annotated difference between `@ContextConfiguration` and `@SpringJUnitConfig` is that component
classes may be declared with the `value` attribute in `@SpringJUnitConfig`. classes may be declared with the `value` attribute in `@SpringJUnitConfig`.
The following example shows how to use the `@SpringJUnitConfig` annotation to specify a The following example shows how to use the `@SpringJUnitConfig` annotation to specify a
@ -1696,7 +1697,7 @@ and `@ContextConfiguration` for further details.
`@WebAppConfiguration` from the Spring TestContext Framework. You can use it at the class `@WebAppConfiguration` from the Spring TestContext Framework. You can use it at the class
level as a drop-in replacement for `@ContextConfiguration` and `@WebAppConfiguration`. level as a drop-in replacement for `@ContextConfiguration` and `@WebAppConfiguration`.
With regard to configuration options, the only difference between `@ContextConfiguration` With regard to configuration options, the only difference between `@ContextConfiguration`
and `@SpringJUnitWebConfig` is that you can declare annotated classes by using the and `@SpringJUnitWebConfig` is that you can declare component classes by using the
`value` attribute in `@SpringJUnitWebConfig`. In addition, you can override the `value` `value` attribute in `@SpringJUnitWebConfig`. In addition, you can override the `value`
attribute from `@WebAppConfiguration` only by using the `resourcePath` attribute in attribute from `@WebAppConfiguration` only by using the `resourcePath` attribute in
`@SpringJUnitWebConfig`. `@SpringJUnitWebConfig`.
@ -2215,13 +2216,13 @@ the `TestContextManager` with which the listener is registered. See <<testcontex
`ContextLoader` is a strategy interface for loading an `ApplicationContext` for an `ContextLoader` is a strategy interface for loading an `ApplicationContext` for an
integration test managed by the Spring TestContext Framework. You should implement integration test managed by the Spring TestContext Framework. You should implement
`SmartContextLoader` instead of this interface to provide support for annotated classes, `SmartContextLoader` instead of this interface to provide support for component classes,
active bean definition profiles, test property sources, context hierarchies, and active bean definition profiles, test property sources, context hierarchies, and
`WebApplicationContext` support. `WebApplicationContext` support.
`SmartContextLoader` is an extension of the `ContextLoader` interface introduced in `SmartContextLoader` is an extension of the `ContextLoader` interface introduced in
Spring 3.1, superseding the original minimal `ContextLoader` SPI. Specifically, a Spring 3.1, superseding the original minimal `ContextLoader` SPI. Specifically, a
`SmartContextLoader` can choose to process resource locations, annotated classes, `SmartContextLoader` can choose to process resource locations, component classes,
or context initializers. Furthermore, a `SmartContextLoader` can set active bean or context initializers. Furthermore, a `SmartContextLoader` can set active bean
definition profiles and test property sources in the context that it loads. definition profiles and test property sources in the context that it loads.
@ -2238,9 +2239,9 @@ Spring provides the following implementations:
the test class or on the presence of default locations or default configuration the test class or on the presence of default locations or default configuration
classes. A web `ContextLoader` is used only if `@WebAppConfiguration` is present on the classes. A web `ContextLoader` is used only if `@WebAppConfiguration` is present on the
test class. Groovy support is enabled only if Groovy is on the classpath. test class. Groovy support is enabled only if Groovy is on the classpath.
* `AnnotationConfigContextLoader`: Loads a standard `ApplicationContext` from annotated * `AnnotationConfigContextLoader`: Loads a standard `ApplicationContext` from component
classes. classes.
* `AnnotationConfigWebContextLoader`: Loads a `WebApplicationContext` from annotated * `AnnotationConfigWebContextLoader`: Loads a `WebApplicationContext` from component
classes. classes.
* `GenericGroovyXmlContextLoader`: Loads a standard `ApplicationContext` from resource * `GenericGroovyXmlContextLoader`: Loads a standard `ApplicationContext` from resource
locations that are either Groovy scripts or XML configuration files. locations that are either Groovy scripts or XML configuration files.
@ -2589,14 +2590,14 @@ Test classes that use the TestContext framework do not need to extend any partic
class or implement a specific interface to configure their application context. Instead, class or implement a specific interface to configure their application context. Instead,
configuration is achieved by declaring the `@ContextConfiguration` annotation at the configuration is achieved by declaring the `@ContextConfiguration` annotation at the
class level. If your test class does not explicitly declare application context resource class level. If your test class does not explicitly declare application context resource
locations or annotated classes, the configured `ContextLoader` determines how to load a locations or component classes, the configured `ContextLoader` determines how to load a
context from a default location or default configuration classes. In addition to context context from a default location or default configuration classes. In addition to context
resource locations and annotated classes, an application context can also be configured resource locations and component classes, an application context can also be configured
through application context initializers. through application context initializers.
The following sections explain how to use Spring's `@ContextConfiguration` annotation to The following sections explain how to use Spring's `@ContextConfiguration` annotation to
configure a test `ApplicationContext` by using XML configuration files, Groovy scripts, configure a test `ApplicationContext` by using XML configuration files, Groovy scripts,
annotated classes (typically `@Configuration` classes), or context initializers. component classes (typically `@Configuration` classes), or context initializers.
Alternatively, you can implement and configure your own custom `SmartContextLoader` for Alternatively, you can implement and configure your own custom `SmartContextLoader` for
advanced use cases. advanced use cases.
@ -2828,12 +2829,12 @@ The following listing shows how to combine both in an integration test:
===== =====
[[testcontext-ctx-management-javaconfig]] [[testcontext-ctx-management-javaconfig]]
===== Context Configuration with Annotated Classes ===== Context Configuration with Component Classes
To load an `ApplicationContext` for your tests by using annotated classes (see To load an `ApplicationContext` for your tests by using component classes (see
<<core.adoc#beans-java, Java-based container configuration>>), you can annotate your test <<core.adoc#beans-java, Java-based container configuration>>), you can annotate your test
class with `@ContextConfiguration` and configure the `classes` attribute with an array class with `@ContextConfiguration` and configure the `classes` attribute with an array
that contains references to annotated classes. The following example shows how to do so: that contains references to component classes. The following example shows how to do so:
[source,java,indent=0,subs="verbatim,quotes",role="primary"] [source,java,indent=0,subs="verbatim,quotes",role="primary"]
.Java .Java
@ -2845,7 +2846,7 @@ that contains references to annotated classes. The following example shows how t
// class body... // class body...
} }
---- ----
<1> Specifying annotated classes. <1> Specifying component classes.
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
.Kotlin .Kotlin
@ -2857,23 +2858,27 @@ that contains references to annotated classes. The following example shows how t
// class body... // class body...
} }
---- ----
<1> Specifying annotated classes. <1> Specifying component classes.
.Annotated Classes [[testcontext-ctx-management-javaconfig-component-classes]]
.Component Classes
[TIP] [TIP]
==== ====
The term "`annotated class`" can refer to any of the following: The term "`component class`" can refer to any of the following:
* A class annotated with `@Configuration`. * A class annotated with `@Configuration`.
* A component (that is, a class annotated with `@Component`, `@Service`, `@Repository`, or other stereotype annotations). * A component (that is, a class annotated with `@Component`, `@Service`, `@Repository`, or other stereotype annotations).
* A JSR-330 compliant class that is annotated with `javax.inject` annotations. * A JSR-330 compliant class that is annotated with `javax.inject` annotations.
* Any other class that contains `@Bean` methods. * Any class that contains `@Bean`-methods.
* Any other class that is intended to be registered as a Spring component (i.e., a Spring
bean in the `ApplicationContext`), potentially taking advantage of automatic autowiring
of a single constructor without the use of Spring annotations.
See the javadoc of See the javadoc of
{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and {api-spring-framework}/context/annotation/Configuration.html[`@Configuration`] and
{api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information {api-spring-framework}/context/annotation/Bean.html[`@Bean`] for further information
regarding the configuration and semantics of annotated classes, paying special attention regarding the configuration and semantics of component classes, paying special attention
to the discussion of `@Bean` Lite Mode. to the discussion of `@Bean` Lite Mode.
==== ====
@ -2952,10 +2957,10 @@ class:
[[testcontext-ctx-management-mixed-config]] [[testcontext-ctx-management-mixed-config]]
===== Mixing XML, Groovy Scripts, and Annotated Classes ===== Mixing XML, Groovy Scripts, and Component Classes
It may sometimes be desirable to mix XML configuration files, Groovy scripts, and It may sometimes be desirable to mix XML configuration files, Groovy scripts, and
annotated classes (typically `@Configuration` classes) to configure an component classes (typically `@Configuration` classes) to configure an
`ApplicationContext` for your tests. For example, if you use XML configuration in `ApplicationContext` for your tests. For example, if you use XML configuration in
production, you may decide that you want to use `@Configuration` classes to configure production, you may decide that you want to use `@Configuration` classes to configure
specific Spring-managed components for your tests, or vice versa. specific Spring-managed components for your tests, or vice versa.
@ -3031,7 +3036,7 @@ order in which the initializers are invoked depends on whether they implement Sp
You can also omit the declaration of XML configuration files, Groovy scripts, or You can also omit the declaration of XML configuration files, Groovy scripts, or
annotated classes in `@ContextConfiguration` entirely and instead declare only component classes in `@ContextConfiguration` entirely and instead declare only
`ApplicationContextInitializer` classes, which are then responsible for registering beans `ApplicationContextInitializer` classes, which are then responsible for registering beans
in the context -- for example, by programmatically loading bean definitions from XML in the context -- for example, by programmatically loading bean definitions from XML
files or configuration classes. The following example shows how to do so: files or configuration classes. The following example shows how to do so:
@ -3067,18 +3072,18 @@ files or configuration classes. The following example shows how to do so:
===== Context Configuration Inheritance ===== Context Configuration Inheritance
`@ContextConfiguration` supports boolean `inheritLocations` and `inheritInitializers` `@ContextConfiguration` supports boolean `inheritLocations` and `inheritInitializers`
attributes that denote whether resource locations or annotated classes and context attributes that denote whether resource locations or component classes and context
initializers declared by superclasses should be inherited. The default value for both initializers declared by superclasses should be inherited. The default value for both
flags is `true`. This means that a test class inherits the resource locations or flags is `true`. This means that a test class inherits the resource locations or
annotated classes as well as the context initializers declared by any superclasses. component classes as well as the context initializers declared by any superclasses.
Specifically, the resource locations or annotated classes for a test class are appended Specifically, the resource locations or component classes for a test class are appended
to the list of resource locations or annotated classes declared by superclasses. to the list of resource locations or annotated classes declared by superclasses.
Similarly, the initializers for a given test class are added to the set of initializers Similarly, the initializers for a given test class are added to the set of initializers
defined by test superclasses. Thus, subclasses have the option of extending the resource defined by test superclasses. Thus, subclasses have the option of extending the resource
locations, annotated classes, or context initializers. locations, component classes, or context initializers.
If the `inheritLocations` or `inheritInitializers` attribute in `@ContextConfiguration` If the `inheritLocations` or `inheritInitializers` attribute in `@ContextConfiguration`
is set to `false`, the resource locations or annotated classes and the context is set to `false`, the resource locations or component classes and the context
initializers, respectively, for the test class shadow and effectively replace the initializers, respectively, for the test class shadow and effectively replace the
configuration defined by superclasses. configuration defined by superclasses.
@ -3131,7 +3136,7 @@ another and use both its own configuration file and the superclass's configurati
<2> Configuration file defined in the subclass. <2> Configuration file defined in the subclass.
Similarly, in the next example, which uses annotated classes, the `ApplicationContext` Similarly, in the next example, which uses component classes, the `ApplicationContext`
for `ExtendedTest` is loaded from the `BaseConfig` and `ExtendedConfig` classes, in that for `ExtendedTest` is loaded from the `BaseConfig` and `ExtendedConfig` classes, in that
order. Beans defined in `ExtendedConfig` can, therefore, override (that is, replace) order. Beans defined in `ExtendedConfig` can, therefore, override (that is, replace)
those defined in `BaseConfig`. The following example shows how one class can extend those defined in `BaseConfig`. The following example shows how one class can extend
@ -4027,7 +4032,7 @@ framework's support for convention over configuration:
If you annotate a test class with `@WebAppConfiguration` without specifying a resource If you annotate a test class with `@WebAppConfiguration` without specifying a resource
base path, the resource path effectively defaults to `file:src/main/webapp`. Similarly, base path, the resource path effectively defaults to `file:src/main/webapp`. Similarly,
if you declare `@ContextConfiguration` without specifying resource `locations`, annotated if you declare `@ContextConfiguration` without specifying resource `locations`, component
`classes`, or context `initializers`, Spring tries to detect the presence of your `classes`, or context `initializers`, Spring tries to detect the presence of your
configuration by using conventions (that is, `WacTests-context.xml` in the same package configuration by using conventions (that is, `WacTests-context.xml` in the same package
as the `WacTests` class or static nested `@Configuration` classes). as the `WacTests` class or static nested `@Configuration` classes).
@ -4280,7 +4285,7 @@ either on an individual test class or within a test class hierarchy. If a contex
hierarchy is declared on multiple classes within a test class hierarchy, you can also hierarchy is declared on multiple classes within a test class hierarchy, you can also
merge or override the context configuration for a specific, named level in the context merge or override the context configuration for a specific, named level in the context
hierarchy. When merging configuration for a given level in the hierarchy, the hierarchy. When merging configuration for a given level in the hierarchy, the
configuration resource type (that is, XML configuration files or annotated classes) must configuration resource type (that is, XML configuration files or component classes) must
be consistent. Otherwise, it is perfectly acceptable to have different levels in a be consistent. Otherwise, it is perfectly acceptable to have different levels in a
context hierarchy configured using different resource types. context hierarchy configured using different resource types.