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