org.springframework.test.context.SmartContextLoader Maven / Gradle / Ivy
Show all versions of spring-test Show documentation
/*
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.context;
import org.springframework.context.ApplicationContext;
import org.springframework.lang.Nullable;
/**
* Strategy interface for loading an {@link ApplicationContext} for an integration
* test managed by the Spring TestContext Framework.
*
* The {@code SmartContextLoader} SPI supersedes the {@link ContextLoader} SPI
* introduced in Spring 2.5: a {@code SmartContextLoader} can choose to process
* resource locations, component classes, or a combination of both. Furthermore, a
* {@code SmartContextLoader} can configure the context that it
* {@linkplain #loadContext(MergedContextConfiguration) loads} based on any
* properties available in the provided {@link MergedContextConfiguration}.
* For example, active bean definition profiles can be configured for the context
* based on {@link MergedContextConfiguration#getActiveProfiles()}.
*
*
See the Javadoc for {@link ContextConfiguration @ContextConfiguration}
* for a definition of component classes.
*
*
Clients of a {@code SmartContextLoader} should call
* {@link #processContextConfiguration(ContextConfigurationAttributes)
* processContextConfiguration()} prior to calling
* {@link #loadContext(MergedContextConfiguration) loadContext()}. This gives a
* {@code SmartContextLoader} the opportunity to provide custom support for
* modifying resource locations or detecting default resource locations or
* default configuration classes. The results of
* {@link #processContextConfiguration(ContextConfigurationAttributes)
* processContextConfiguration()} should be merged for all classes in the
* hierarchy of the root test class and then supplied to
* {@link #loadContext(MergedContextConfiguration) loadContext()}.
*
*
NOTE: As of Spring Framework 6.0, {@code SmartContextLoader} no longer
* supports methods defined in the {@code ContextLoader} SPI.
*
*
Concrete implementations must provide a {@code public} no-args constructor.
*
*
Spring provides the following {@code SmartContextLoader} implementations.
*
* - {@link org.springframework.test.context.support.DelegatingSmartContextLoader DelegatingSmartContextLoader}
* - {@link org.springframework.test.context.support.AnnotationConfigContextLoader AnnotationConfigContextLoader}
* - {@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader}
* - {@link org.springframework.test.context.support.GenericGroovyXmlContextLoader GenericGroovyXmlContextLoader}
* - {@link org.springframework.test.context.web.WebDelegatingSmartContextLoader WebDelegatingSmartContextLoader}
* - {@link org.springframework.test.context.web.AnnotationConfigWebContextLoader AnnotationConfigWebContextLoader}
* - {@link org.springframework.test.context.web.GenericXmlWebContextLoader GenericXmlWebContextLoader}
* - {@link org.springframework.test.context.web.GenericGroovyXmlWebContextLoader GenericGroovyXmlWebContextLoader}
*
*
* @author Sam Brannen
* @since 3.1
* @see ContextConfiguration
* @see ActiveProfiles
* @see TestPropertySource
* @see ContextConfigurationAttributes
* @see MergedContextConfiguration
*/
public interface SmartContextLoader extends ContextLoader {
/**
* Process the {@link ContextConfigurationAttributes} for a given test class.
* Concrete implementations may choose to modify the {@code locations}
* or {@code classes} in the supplied {@code ContextConfigurationAttributes},
* generate default configuration locations, or detect
* default configuration classes if the supplied values are {@code null}
* or empty.
*
Note: a {@code SmartContextLoader} must preemptively
* verify that a generated or detected default actually exists before setting
* the corresponding {@code locations} or {@code classes} property in the
* supplied {@code ContextConfigurationAttributes}. Consequently, leaving the
* {@code locations} or {@code classes} property empty signals that this
* {@code SmartContextLoader} was not able to generate or detect defaults.
* @param configAttributes the context configuration attributes to process
*/
void processContextConfiguration(ContextConfigurationAttributes configAttributes);
/**
* Load a new {@link ApplicationContext} based on the supplied
* {@link MergedContextConfiguration}, configure the context, and return the
* context in a fully refreshed state.
*
Concrete implementations should register annotation configuration
* processors with bean factories of
* {@link ApplicationContext application contexts} loaded by this
* {@code SmartContextLoader}. Beans will therefore automatically be
* candidates for annotation-based dependency injection using
* {@link org.springframework.beans.factory.annotation.Autowired @Autowired},
* {@link jakarta.annotation.Resource @Resource}, and
* {@link jakarta.inject.Inject @Inject}. In addition, concrete implementations
* should perform the following actions.
*
* - Set the parent {@code ApplicationContext} if appropriate (see
* {@link MergedContextConfiguration#getParent()}).
* - Set the active bean definition profiles in the context's
* {@link org.springframework.core.env.Environment Environment} (see
* {@link MergedContextConfiguration#getActiveProfiles()}).
* - Add test {@link org.springframework.core.env.PropertySource PropertySources}
* to the {@code Environment} (see
* {@link MergedContextConfiguration#getPropertySourceLocations()},
* {@link MergedContextConfiguration#getPropertySourceProperties()}, and
* {@link org.springframework.test.context.support.TestPropertySourceUtils
* TestPropertySourceUtils}).
* - Invoke {@link org.springframework.context.ApplicationContextInitializer
* ApplicationContextInitializers} (see
* {@link MergedContextConfiguration#getContextInitializerClasses()}).
* - Invoke {@link ContextCustomizer ContextCustomizers} (see
* {@link MergedContextConfiguration#getContextCustomizers()}).
* - Register a JVM shutdown hook for the {@link ApplicationContext}. Unless
* the context gets closed early, all context instances will be automatically
* closed on JVM shutdown. This allows for freeing of external resources held
* by beans within the context — for example, temporary files.
*
* As of Spring Framework 6.0, any exception thrown while attempting to
* load an {@code ApplicationContext} should be wrapped in a
* {@link ContextLoadException}. Concrete implementations should therefore
* contain a try-catch block similar to the following.
*
* ApplicationContext context = // create context
* try {
* // configure and refresh context
* }
* catch (Exception ex) {
* throw new ContextLoadException(context, ex);
* }
*
* @param mergedConfig the merged context configuration to use to load the
* application context
* @return a new application context
* @throws ContextLoadException if context loading failed
* @see #processContextConfiguration(ContextConfigurationAttributes)
* @see org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)
* @see org.springframework.context.ConfigurableApplicationContext#getEnvironment()
*/
ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception;
/**
* {@code SmartContextLoader} does not support deprecated {@link ContextLoader} methods.
* Call {@link #processContextConfiguration(ContextConfigurationAttributes)} instead.
* @throws UnsupportedOperationException in this implementation
* @since 6.0
*/
@Override
@SuppressWarnings("deprecation")
default String[] processLocations(Class> clazz, @Nullable String... locations) {
throw new UnsupportedOperationException("""
SmartContextLoader does not support the ContextLoader SPI. \
Call processContextConfiguration(ContextConfigurationAttributes) instead.""");
}
/**
* {@code SmartContextLoader} does not support deprecated {@link ContextLoader} methods.
* Call {@link #loadContext(MergedContextConfiguration)} instead.
* @throws UnsupportedOperationException in this implementation
* @since 6.0
*/
@Override
@SuppressWarnings("deprecation")
default ApplicationContext loadContext(String... locations) throws Exception {
throw new UnsupportedOperationException("""
SmartContextLoader does not support the ContextLoader SPI. \
Call loadContext(MergedContextConfiguration) instead.""");
}
}