1 /* 2 * Copyright 2002-2011 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.test.context; 18 19 import org.springframework.context.ApplicationContext; 20 21 /** 22 * Strategy interface for loading an {@link ApplicationContext application context} 23 * for an integration test managed by the Spring TestContext Framework. 24 * 25 * <p>The {@code SmartContextLoader} SPI supersedes the {@link ContextLoader} SPI 26 * introduced in Spring 2.5: a {@code SmartContextLoader} can choose to process 27 * either resource locations or configuration classes. Furthermore, a 28 * {@code SmartContextLoader} can set active bean definition profiles in the 29 * context that it loads (see {@link MergedContextConfiguration#getActiveProfiles()} 30 * and {@link #loadContext(MergedContextConfiguration)}). 31 * 32 * <p>Clients of a {@code SmartContextLoader} should call 33 * {@link #processContextConfiguration(ContextConfigurationAttributes) 34 * processContextConfiguration()} prior to calling 35 * {@link #loadContext(MergedContextConfiguration) loadContext()}. This gives a 36 * {@code SmartContextLoader} the opportunity to provide custom support for 37 * modifying resource locations or detecting default resource locations or 38 * default configuration classes. The results of 39 * {@link #processContextConfiguration(ContextConfigurationAttributes) 40 * processContextConfiguration()} should be merged for all classes in the 41 * hierarchy of the root test class and then supplied to 42 * {@link #loadContext(MergedContextConfiguration) loadContext()}. 43 * 44 * <p>Even though {@code SmartContextLoader} extends {@code ContextLoader}, 45 * clients should favor {@code SmartContextLoader}-specific methods over those 46 * defined in {@code ContextLoader}, particularly because a 47 * {@code SmartContextLoader} may choose not to support methods defined in 48 * the {@code ContextLoader} SPI. 49 * 50 * <p>Concrete implementations must provide a <code>public</code> no-args constructor. 51 * 52 * <p>Spring provides the following out-of-the-box implementations: 53 * <ul> 54 * <li>{@link org.springframework.test.context.support.DelegatingSmartContextLoader DelegatingSmartContextLoader}</li> 55 * <li>{@link org.springframework.test.context.support.AnnotationConfigContextLoader AnnotationConfigContextLoader}</li> 56 * <li>{@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader}</li> 57 * <li>{@link org.springframework.test.context.support.GenericPropertiesContextLoader GenericPropertiesContextLoader}</li> 58 * </ul> 59 * 60 * @author Sam Brannen 61 * @since 3.1 62 * @see ContextConfiguration 63 * @see ActiveProfiles 64 * @see ContextConfigurationAttributes 65 * @see MergedContextConfiguration 66 */ 67 public interface SmartContextLoader extends ContextLoader { 68 69 /** 70 * Processes the {@link ContextConfigurationAttributes} for a given test class. 71 * <p>Concrete implementations may choose to <em>modify</em> the <code>locations</code> 72 * or <code>classes</code> in the supplied {@link ContextConfigurationAttributes}, 73 * <em>generate</em> default configuration locations, or <em>detect</em> 74 * default configuration classes if the supplied values are <code>null</code> 75 * or empty. 76 * <p><b>Note</b>: in contrast to a standard {@code ContextLoader}, a 77 * {@code SmartContextLoader} <b>must</b> <em>preemptively</em> verify that 78 * a generated or detected default actually exists before setting the corresponding 79 * <code>locations</code> or <code>classes</code> property in the supplied 80 * {@link ContextConfigurationAttributes}. Consequently, leaving the 81 * <code>locations</code> or <code>classes</code> property empty signals that 82 * this {@code SmartContextLoader} was not able to generate or detect defaults. 83 * @param configAttributes the context configuration attributes to process 84 */ processContextConfiguration(ContextConfigurationAttributes configAttributes)85 void processContextConfiguration(ContextConfigurationAttributes configAttributes); 86 87 /** 88 * Loads a new {@link ApplicationContext context} based on the supplied 89 * {@link MergedContextConfiguration merged context configuration}, 90 * configures the context, and finally returns the context in a fully 91 * <em>refreshed</em> state. 92 * <p>Concrete implementations should register annotation configuration 93 * processors with bean factories of 94 * {@link ApplicationContext application contexts} loaded by this 95 * {@code SmartContextLoader}. Beans will therefore automatically be 96 * candidates for annotation-based dependency injection using 97 * {@link org.springframework.beans.factory.annotation.Autowired @Autowired}, 98 * {@link javax.annotation.Resource @Resource}, and 99 * {@link javax.inject.Inject @Inject}. In addition, concrete implementations 100 * should set the active bean definition profiles in the context's 101 * {@link org.springframework.core.env.Environment Environment}. 102 * <p>Any <code>ApplicationContext</code> loaded by a 103 * {@code SmartContextLoader} <strong>must</strong> register a JVM 104 * shutdown hook for itself. Unless the context gets closed early, all context 105 * instances will be automatically closed on JVM shutdown. This allows for 106 * freeing of external resources held by beans within the context (e.g., 107 * temporary files). 108 * @param mergedConfig the merged context configuration to use to load the 109 * application context 110 * @return a new application context 111 * @throws Exception if context loading failed 112 * @see #processContextConfiguration(ContextConfigurationAttributes) 113 * @see org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors() 114 * @see org.springframework.test.context.MergedContextConfiguration#getActiveProfiles() 115 * @see org.springframework.context.ConfigurableApplicationContext#getEnvironment() 116 */ loadContext(MergedContextConfiguration mergedConfig)117 ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception; 118 119 } 120