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