001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.test.context;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Inherited;
022import java.lang.annotation.Retention;
023import java.lang.annotation.RetentionPolicy;
024import java.lang.annotation.Target;
025
026import org.springframework.context.ApplicationContextInitializer;
027import org.springframework.context.ConfigurableApplicationContext;
028import org.springframework.core.annotation.AliasFor;
029
030/**
031 * {@code @ContextConfiguration} defines class-level metadata that is used to determine
032 * how to load and configure an {@link org.springframework.context.ApplicationContext
033 * ApplicationContext} for integration tests.
034 *
035 * <h3>Supported Resource Types</h3>
036 *
037 * <p>Prior to Spring 3.1, only path-based resource locations (typically XML configuration
038 * files) were supported. As of Spring 3.1, {@linkplain #loader context loaders} may
039 * choose to support <em>either</em> path-based <em>or</em> class-based resources. As of
040 * Spring 4.0.4, {@linkplain #loader context loaders} may choose to support path-based
041 * <em>and</em> class-based resources simultaneously. Consequently
042 * {@code @ContextConfiguration} can be used to declare either path-based resource
043 * locations (via the {@link #locations} or {@link #value} attribute) <em>or</em>
044 * component classes (via the {@link #classes} attribute). Note, however, that most
045 * implementations of {@link SmartContextLoader} only support a single resource type. As
046 * of Spring 4.1, path-based resource locations may be either XML configuration files or
047 * Groovy scripts (if Groovy is on the classpath). Of course, third-party frameworks may
048 * choose to support additional types of path-based resources.
049 *
050 * <h3>Component Classes</h3>
051 *
052 * <p>The term <em>component class</em> can refer to any of the following.
053 *
054 * <ul>
055 * <li>A class annotated with {@link org.springframework.context.annotation.Configuration @Configuration}</li>
056 * <li>A component (i.e., a class annotated with
057 * {@link org.springframework.stereotype.Component @Component},
058 * {@link org.springframework.stereotype.Service @Service},
059 * {@link org.springframework.stereotype.Repository @Repository}, etc.)</li>
060 * <li>A JSR-330 compliant class that is annotated with {@code javax.inject} annotations</li>
061 * <li>Any class that contains {@link org.springframework.context.annotation.Bean @Bean}-methods</li>
062 * <li>Any other class that is intended to be registered as a Spring component (i.e., a Spring bean
063 * in the {@code ApplicationContext}), potentially taking advantage of automatic autowiring of a
064 * single constructor without the use of Spring annotations</li>
065 * </ul>
066 *
067 * A bean will be registered in the {@code ApplicationContext} for each component
068 * class, and such beans can therefore be injected into other beans or into the
069 * instance of the test class.
070 *
071 * <p>Consult the Javadoc for {@link org.springframework.context.annotation.Configuration @Configuration}
072 * and {@link org.springframework.context.annotation.Bean @Bean} for further
073 * information regarding the configuration and semantics of <em>component classes</em>.
074 *
075 * <p>This annotation may be used as a <em>meta-annotation</em> to create custom
076 * <em>composed annotations</em>.
077 *
078 * @author Sam Brannen
079 * @since 2.5
080 * @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig @SpringJUnitConfig
081 * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig @SpringJUnitWebConfig
082 * @see ContextHierarchy @ContextHierarchy
083 * @see ActiveProfiles @ActiveProfiles
084 * @see TestPropertySource @TestPropertySource
085 * @see SmartContextLoader
086 * @see ContextConfigurationAttributes
087 * @see MergedContextConfiguration
088 * @see org.springframework.context.ApplicationContext ApplicationContext
089 */
090@Target(ElementType.TYPE)
091@Retention(RetentionPolicy.RUNTIME)
092@Documented
093@Inherited
094public @interface ContextConfiguration {
095
096        /**
097         * Alias for {@link #locations}.
098         * <p>This attribute may <strong>not</strong> be used in conjunction with
099         * {@link #locations}, but it may be used instead of {@link #locations}.
100         * @since 3.0
101         * @see #inheritLocations
102         */
103        @AliasFor("locations")
104        String[] value() default {};
105
106        /**
107         * The resource locations to use for loading an
108         * {@link org.springframework.context.ApplicationContext ApplicationContext}.
109         * <p>Check out the Javadoc for
110         * {@link org.springframework.test.context.support.AbstractContextLoader#modifyLocations
111         * AbstractContextLoader.modifyLocations()} for details on how a location
112         * will be interpreted at runtime, in particular in case of a relative
113         * path. Also, check out the documentation on
114         * {@link org.springframework.test.context.support.AbstractContextLoader#generateDefaultLocations
115         * AbstractContextLoader.generateDefaultLocations()} for details on the
116         * default locations that are going to be used if none are specified.
117         * <p>Note that the aforementioned default rules only apply for a standard
118         * {@link org.springframework.test.context.support.AbstractContextLoader
119         * AbstractContextLoader} subclass such as
120         * {@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader} or
121         * {@link org.springframework.test.context.support.GenericGroovyXmlContextLoader GenericGroovyXmlContextLoader}
122         * which are the effective default implementations used at runtime if
123         * {@code locations} are configured. See the documentation for {@link #loader}
124         * for further details regarding default loaders.
125         * <p>This attribute may <strong>not</strong> be used in conjunction with
126         * {@link #value}, but it may be used instead of {@link #value}.
127         * @since 2.5
128         * @see #inheritLocations
129         */
130        @AliasFor("value")
131        String[] locations() default {};
132
133        /**
134         * The <em>component classes</em> to use for loading an
135         * {@link org.springframework.context.ApplicationContext ApplicationContext}.
136         * <p>Check out the javadoc for
137         * {@link org.springframework.test.context.support.AnnotationConfigContextLoader#detectDefaultConfigurationClasses
138         * AnnotationConfigContextLoader.detectDefaultConfigurationClasses()} for details
139         * on how default configuration classes will be detected if no
140         * <em>component classes</em> are specified. See the documentation for
141         * {@link #loader} for further details regarding default loaders.
142         * @since 3.1
143         * @see org.springframework.context.annotation.Configuration
144         * @see org.springframework.test.context.support.AnnotationConfigContextLoader
145         * @see #inheritLocations
146         */
147        Class<?>[] classes() default {};
148
149        /**
150         * The application context <em>initializer classes</em> to use for initializing
151         * a {@link ConfigurableApplicationContext}.
152         * <p>The concrete {@code ConfigurableApplicationContext} type supported by each
153         * declared initializer must be compatible with the type of {@code ApplicationContext}
154         * created by the {@link SmartContextLoader} in use.
155         * <p>{@code SmartContextLoader} implementations typically detect whether
156         * Spring's {@link org.springframework.core.Ordered Ordered} interface has been
157         * implemented or if the @{@link org.springframework.core.annotation.Order Order}
158         * annotation is present and sort instances accordingly prior to invoking them.
159         * @since 3.2
160         * @see org.springframework.context.ApplicationContextInitializer
161         * @see org.springframework.context.ConfigurableApplicationContext
162         * @see #inheritInitializers
163         * @see #loader
164         */
165        Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
166
167        /**
168         * Whether or not {@linkplain #locations resource locations} or
169         * {@linkplain #classes <em>component classes</em>} from test superclasses
170         * should be <em>inherited</em>.
171         * <p>The default value is {@code true}. This means that an annotated test
172         * class will <em>inherit</em> the resource locations or component classes
173         * defined by test superclasses. Specifically, the resource locations or
174         * component classes for a given test class will be appended to the list of
175         * resource locations or component classes defined by test superclasses.
176         * Thus, subclasses have the option of <em>extending</em> the list of resource
177         * locations or component classes.
178         * <p>If {@code inheritLocations} is set to {@code false}, the
179         * resource locations or component classes for the annotated test class
180         * will <em>shadow</em> and effectively replace any resource locations
181         * or component classes defined by superclasses.
182         * <p>In the following example that uses path-based resource locations, the
183         * {@link org.springframework.context.ApplicationContext ApplicationContext}
184         * for {@code ExtendedTest} will be loaded from
185         * {@code "base-context.xml"} <strong>and</strong>
186         * {@code "extended-context.xml"}, in that order. Beans defined in
187         * {@code "extended-context.xml"} may therefore override those defined
188         * in {@code "base-context.xml"}.
189         * <pre class="code">
190         * &#064;ContextConfiguration("base-context.xml")
191         * public class BaseTest {
192         *     // ...
193         * }
194         *
195         * &#064;ContextConfiguration("extended-context.xml")
196         * public class ExtendedTest extends BaseTest {
197         *     // ...
198         * }
199         * </pre>
200         * <p>Similarly, in the following example that uses component classes, the
201         * {@link org.springframework.context.ApplicationContext ApplicationContext}
202         * for {@code ExtendedTest} will be loaded from the
203         * {@code BaseConfig} <strong>and</strong> {@code ExtendedConfig}
204         * configuration classes, in that order. Beans defined in
205         * {@code ExtendedConfig} may therefore override those defined in
206         * {@code BaseConfig}.
207         * <pre class="code">
208         * &#064;ContextConfiguration(classes=BaseConfig.class)
209         * public class BaseTest {
210         *     // ...
211         * }
212         *
213         * &#064;ContextConfiguration(classes=ExtendedConfig.class)
214         * public class ExtendedTest extends BaseTest {
215         *     // ...
216         * }
217         * </pre>
218         * @since 2.5
219         */
220        boolean inheritLocations() default true;
221
222        /**
223         * Whether or not {@linkplain #initializers context initializers} from test
224         * superclasses should be <em>inherited</em>.
225         * <p>The default value is {@code true}. This means that an annotated test
226         * class will <em>inherit</em> the application context initializers defined
227         * by test superclasses. Specifically, the initializers for a given test
228         * class will be added to the set of initializers defined by test
229         * superclasses. Thus, subclasses have the option of <em>extending</em> the
230         * set of initializers.
231         * <p>If {@code inheritInitializers} is set to {@code false}, the initializers
232         * for the annotated test class will <em>shadow</em> and effectively replace
233         * any initializers defined by superclasses.
234         * <p>In the following example, the
235         * {@link org.springframework.context.ApplicationContext ApplicationContext}
236         * for {@code ExtendedTest} will be initialized using
237         * {@code BaseInitializer} <strong>and</strong> {@code ExtendedInitializer}.
238         * Note, however, that the order in which the initializers are invoked
239         * depends on whether they implement {@link org.springframework.core.Ordered
240         * Ordered} or are annotated with {@link org.springframework.core.annotation.Order
241         * &#064;Order}.
242         * <pre class="code">
243         * &#064;ContextConfiguration(initializers = BaseInitializer.class)
244         * public class BaseTest {
245         *     // ...
246         * }
247         *
248         * &#064;ContextConfiguration(initializers = ExtendedInitializer.class)
249         * public class ExtendedTest extends BaseTest {
250         *     // ...
251         * }
252         * </pre>
253         * @since 3.2
254         */
255        boolean inheritInitializers() default true;
256
257        /**
258         * The type of {@link SmartContextLoader} (or {@link ContextLoader}) to use
259         * for loading an {@link org.springframework.context.ApplicationContext
260         * ApplicationContext}.
261         * <p>If not specified, the loader will be inherited from the first superclass
262         * that is annotated or meta-annotated with {@code @ContextConfiguration} and
263         * specifies an explicit loader. If no class in the hierarchy specifies an
264         * explicit loader, a default loader will be used instead.
265         * <p>The default concrete implementation chosen at runtime will be either
266         * {@link org.springframework.test.context.support.DelegatingSmartContextLoader
267         * DelegatingSmartContextLoader} or
268         * {@link org.springframework.test.context.web.WebDelegatingSmartContextLoader
269         * WebDelegatingSmartContextLoader} depending on the absence or presence of
270         * {@link org.springframework.test.context.web.WebAppConfiguration
271         * &#064;WebAppConfiguration}. For further details on the default behavior
272         * of various concrete {@code SmartContextLoaders}, check out the Javadoc for
273         * {@link org.springframework.test.context.support.AbstractContextLoader AbstractContextLoader},
274         * {@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader},
275         * {@link org.springframework.test.context.support.GenericGroovyXmlContextLoader GenericGroovyXmlContextLoader},
276         * {@link org.springframework.test.context.support.AnnotationConfigContextLoader AnnotationConfigContextLoader},
277         * {@link org.springframework.test.context.web.GenericXmlWebContextLoader GenericXmlWebContextLoader},
278         * {@link org.springframework.test.context.web.GenericGroovyXmlWebContextLoader GenericGroovyXmlWebContextLoader}, and
279         * {@link org.springframework.test.context.web.AnnotationConfigWebContextLoader AnnotationConfigWebContextLoader}.
280         * @since 2.5
281         */
282        Class<? extends ContextLoader> loader() default ContextLoader.class;
283
284        /**
285         * The name of the context hierarchy level represented by this configuration.
286         * <p>If not specified the name will be inferred based on the numerical level
287         * within all declared contexts within the hierarchy.
288         * <p>This attribute is only applicable when used within a test class hierarchy
289         * that is configured using {@code @ContextHierarchy}, in which case the name
290         * can be used for <em>merging</em> or <em>overriding</em> this configuration
291         * with configuration of the same name in hierarchy levels defined in superclasses.
292         * See the Javadoc for {@link ContextHierarchy @ContextHierarchy} for details.
293         * @since 3.2.2
294         */
295        String name() default "";
296
297}