001/*
002 * Copyright 2002-2013 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 org.springframework.context.ApplicationContext;
020
021/**
022 * Strategy interface for loading an {@link ApplicationContext application context}
023 * for an integration test managed by the Spring TestContext Framework.
024 *
025 * <p>The {@code SmartContextLoader} SPI supersedes the {@link ContextLoader} SPI
026 * introduced in Spring 2.5: a {@code SmartContextLoader} can choose to process
027 * either resource locations or annotated classes. Furthermore, a
028 * {@code SmartContextLoader} can set active bean definition profiles in the
029 * context that it loads (see {@link MergedContextConfiguration#getActiveProfiles()}
030 * and {@link #loadContext(MergedContextConfiguration)}).
031 *
032 * <p>See the Javadoc for {@link ContextConfiguration @ContextConfiguration}
033 * for a definition of <em>annotated class</em>.
034 *
035 * <p>Clients of a {@code SmartContextLoader} should call
036 * {@link #processContextConfiguration(ContextConfigurationAttributes)
037 * processContextConfiguration()} prior to calling
038 * {@link #loadContext(MergedContextConfiguration) loadContext()}. This gives a
039 * {@code SmartContextLoader} the opportunity to provide custom support for
040 * modifying resource locations or detecting default resource locations or
041 * default configuration classes. The results of
042 * {@link #processContextConfiguration(ContextConfigurationAttributes)
043 * processContextConfiguration()} should be merged for all classes in the
044 * hierarchy of the root test class and then supplied to
045 * {@link #loadContext(MergedContextConfiguration) loadContext()}.
046 *
047 * <p>Even though {@code SmartContextLoader} extends {@code ContextLoader},
048 * clients should favor {@code SmartContextLoader}-specific methods over those
049 * defined in {@code ContextLoader}, particularly because a
050 * {@code SmartContextLoader} may choose not to support methods defined in the
051 * {@code ContextLoader} SPI.
052 *
053 * <p>Concrete implementations must provide a {@code public} no-args constructor.
054 *
055 * <p>Spring provides the following out-of-the-box implementations:
056 * <ul>
057 * <li>{@link org.springframework.test.context.support.DelegatingSmartContextLoader DelegatingSmartContextLoader}</li>
058 * <li>{@link org.springframework.test.context.support.AnnotationConfigContextLoader AnnotationConfigContextLoader}</li>
059 * <li>{@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader}</li>
060 * <li>{@link org.springframework.test.context.support.GenericPropertiesContextLoader GenericPropertiesContextLoader}</li>
061 * <li>{@link org.springframework.test.context.web.WebDelegatingSmartContextLoader WebDelegatingSmartContextLoader}</li>
062 * <li>{@link org.springframework.test.context.web.AnnotationConfigWebContextLoader AnnotationConfigWebContextLoader}</li>
063 * <li>{@link org.springframework.test.context.web.GenericXmlWebContextLoader GenericXmlWebContextLoader}</li>
064 * </ul>
065 *
066 * @author Sam Brannen
067 * @since 3.1
068 * @see ContextConfiguration
069 * @see ActiveProfiles
070 * @see ContextConfigurationAttributes
071 * @see MergedContextConfiguration
072 */
073public interface SmartContextLoader extends ContextLoader {
074
075        /**
076         * Processes the {@link ContextConfigurationAttributes} for a given test class.
077         * <p>Concrete implementations may choose to <em>modify</em> the {@code locations}
078         * or {@code classes} in the supplied {@link ContextConfigurationAttributes},
079         * <em>generate</em> default configuration locations, or <em>detect</em>
080         * default configuration classes if the supplied values are {@code null}
081         * or empty.
082         * <p><b>Note</b>: in contrast to a standard {@code ContextLoader}, a
083         * {@code SmartContextLoader} <b>must</b> <em>preemptively</em> verify that
084         * a generated or detected default actually exists before setting the corresponding
085         * {@code locations} or {@code classes} property in the supplied
086         * {@link ContextConfigurationAttributes}. Consequently, leaving the
087         * {@code locations} or {@code classes} property empty signals that
088         * this {@code SmartContextLoader} was not able to generate or detect defaults.
089         * @param configAttributes the context configuration attributes to process
090         */
091        void processContextConfiguration(ContextConfigurationAttributes configAttributes);
092
093        /**
094         * Loads a new {@link ApplicationContext context} based on the supplied
095         * {@link MergedContextConfiguration merged context configuration},
096         * configures the context, and finally returns the context in a fully
097         * <em>refreshed</em> state.
098         * <p>Concrete implementations should register annotation configuration
099         * processors with bean factories of
100         * {@link ApplicationContext application contexts} loaded by this
101         * {@code SmartContextLoader}. Beans will therefore automatically be
102         * candidates for annotation-based dependency injection using
103         * {@link org.springframework.beans.factory.annotation.Autowired @Autowired},
104         * {@link javax.annotation.Resource @Resource}, and
105         * {@link javax.inject.Inject @Inject}. In addition, concrete implementations
106         * should set the active bean definition profiles in the context's
107         * {@link org.springframework.core.env.Environment Environment}.
108         * <p>Any {@code ApplicationContext} loaded by a
109         * {@code SmartContextLoader} <strong>must</strong> register a JVM
110         * shutdown hook for itself. Unless the context gets closed early, all context
111         * instances will be automatically closed on JVM shutdown. This allows for
112         * freeing of external resources held by beans within the context (e.g.,
113         * temporary files).
114         * @param mergedConfig the merged context configuration to use to load the
115         * application context
116         * @return a new application context
117         * @throws Exception if context loading failed
118         * @see #processContextConfiguration(ContextConfigurationAttributes)
119         * @see org.springframework.context.annotation.AnnotationConfigUtils
120         * #registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)
121         * @see MergedContextConfiguration#getActiveProfiles()
122         * @see org.springframework.context.ConfigurableApplicationContext#getEnvironment()
123         */
124        ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception;
125
126}