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}