Skip to content

Commit a6387dc

Browse files
committed
Document WebApplicationContext support in the TCF
This commit adds Javadoc documentation for the WebApplicationContext testing support that was recently introduced in the Spring TestContext Framework. Issue: SPR-9864
1 parent c8a3562 commit a6387dc

File tree

7 files changed

+236
-37
lines changed

7 files changed

+236
-37
lines changed

spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
import org.apache.commons.logging.Log;
2424
import org.apache.commons.logging.LogFactory;
2525
import org.springframework.context.annotation.Configuration;
26+
import org.springframework.test.context.SmartContextLoader;
2627
import org.springframework.util.Assert;
2728

2829
/**
29-
* TODO [SPR-9864] Document AnnotationConfigContextLoaderUtils.
30+
* Utility methods for {@link SmartContextLoader SmartContextLoaders} that deal
31+
* with annotated classes (e.g., {@link Configuration @Configuration} classes).
3032
*
3133
* @author Sam Brannen
3234
* @since 3.2

spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.commons.logging.Log;
2222
import org.apache.commons.logging.LogFactory;
23+
2324
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
2425
import org.springframework.context.ApplicationContext;
2526
import org.springframework.context.ConfigurableApplicationContext;
@@ -34,10 +35,26 @@
3435
import org.springframework.web.context.support.GenericWebApplicationContext;
3536

3637
/**
37-
* TODO [SPR-9864] Document AbstractGenericWebContextLoader.
38+
* Abstract, generic extension of {@link AbstractContextLoader} that loads a
39+
* {@link GenericWebApplicationContext}.
40+
*
41+
* <p>If instances of concrete subclasses are invoked via the
42+
* {@link org.springframework.test.context.SmartContextLoader SmartContextLoader}
43+
* SPI, the context will be loaded from the {@link MergedContextConfiguration}
44+
* provided to {@link #loadContext(MergedContextConfiguration)}. In such cases, a
45+
* {@code SmartContextLoader} will decide whether to load the context from
46+
* <em>locations</em> or <em>annotated classes</em>. Note that {@code
47+
* AbstractGenericWebContextLoader} does not support the {@code
48+
* loadContext(String... locations)} method from the legacy
49+
* {@link org.springframework.test.context.ContextLoader ContextLoader} SPI.
50+
*
51+
* <p>Concrete subclasses must provide an appropriate implementation of
52+
* {@link #loadBeanDefinitions()}.
3853
*
3954
* @author Sam Brannen
4055
* @since 3.2
56+
* @see #loadContext(MergedContextConfiguration)
57+
* @see #loadContext(String...)
4158
*/
4259
public abstract class AbstractGenericWebContextLoader extends AbstractContextLoader {
4360

@@ -47,9 +64,33 @@ public abstract class AbstractGenericWebContextLoader extends AbstractContextLoa
4764
// --- SmartContextLoader -----------------------------------------------
4865

4966
/**
50-
* TODO [SPR-9864] Document overridden loadContext(MergedContextConfiguration).
67+
* Load a Spring {@link WebApplicationContext} from the supplied
68+
* {@link MergedContextConfiguration}.
69+
*
70+
* <p>Implementation details:
5171
*
52-
* @see org.springframework.test.context.SmartContextLoader#loadContext(org.springframework.test.context.MergedContextConfiguration)
72+
* <ul>
73+
* <li>Creates a {@link GenericWebApplicationContext} instance.</li>
74+
* <li>Delegates to {@link #configureWebResources()} to create the
75+
* {@link MockServletContext} and set it in the {@code WebApplicationContext}.</li>
76+
* <li>Calls {@link #prepareContext()} to allow for customizing the context
77+
* before bean definitions are loaded.</li>
78+
* <li>Calls {@link #customizeBeanFactory()} to allow for customizing the
79+
* context's {@code DefaultListableBeanFactory}.</li>
80+
* <li>Delegates to {@link #loadBeanDefinitions()} to populate the context
81+
* from the locations or classes in the supplied {@code MergedContextConfiguration}.</li>
82+
* <li>Delegates to {@link AnnotationConfigUtils} for
83+
* {@linkplain AnnotationConfigUtils#registerAnnotationConfigProcessors registering}
84+
* annotation configuration processors.</li>
85+
* <li>Calls {@link #customizeContext()} to allow for customizing the context
86+
* before it is refreshed.</li>
87+
* <li>{@link ConfigurableApplicationContext#refresh Refreshes} the
88+
* context and registers a JVM shutdown hook for it.</li>
89+
* </ul>
90+
*
91+
* @return a new web application context
92+
* @see org.springframework.test.context.SmartContextLoader#loadContext(MergedContextConfiguration)
93+
* @see GenericWebApplicationContext
5394
*/
5495
public final ConfigurableApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception {
5596

@@ -78,7 +119,29 @@ public final ConfigurableApplicationContext loadContext(MergedContextConfigurati
78119
}
79120

80121
/**
81-
* TODO [SPR-9864] Document configureWebResources().
122+
* Configures web resources for the supplied web application context.
123+
*
124+
* <p>Implementation details:
125+
*
126+
* <ul>
127+
* <li>The resource base path is retrieved from the supplied
128+
* {@code WebMergedContextConfiguration}.</li>
129+
* <li>A {@link ResourceLoader} is instantiated for the {@link MockServletContext}:
130+
* if the resource base path is prefixed with "{@code classpath:}", a
131+
* {@link DefaultResourceLoader} will be used; otherwise, a
132+
* {@link FileSystemResourceLoader} will be used.</li>
133+
* <li>A {@code MockServletContext} will be created using the resource base
134+
* path and resource loader.</li>
135+
* <li>The supplied {@link GenericWebApplicationContext} is then stored in
136+
* the {@code MockServletContext} under the
137+
* {@link WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE} key.</li>
138+
* <li>Finally, the {@code MockServletContext} is set in the
139+
* {@code WebApplicationContext}.</li>
140+
*
141+
* @param context the web application context for which to configure the web
142+
* resources
143+
* @param webMergedConfig the merged context configuration to use to load the
144+
* web application context
82145
*/
83146
protected void configureWebResources(GenericWebApplicationContext context,
84147
WebMergedContextConfiguration webMergedConfig) {
@@ -93,30 +156,65 @@ protected void configureWebResources(GenericWebApplicationContext context,
93156
}
94157

95158
/**
96-
* TODO [SPR-9864] Document customizeBeanFactory().
159+
* Customize the internal bean factory of the {@code WebApplicationContext}
160+
* created by this context loader.
161+
*
162+
* <p>The default implementation is empty but can be overridden in subclasses
163+
* to customize <code>DefaultListableBeanFactory</code>'s standard settings.
164+
*
165+
* @param beanFactory the bean factory created by this context loader
166+
* @param webMergedConfig the merged context configuration to use to load the
167+
* web application context
168+
* @see #loadContext(MergedContextConfiguration)
169+
* @see DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
170+
* @see DefaultListableBeanFactory#setAllowEagerClassLoading
171+
* @see DefaultListableBeanFactory#setAllowCircularReferences
172+
* @see DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
97173
*/
98174
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory,
99175
WebMergedContextConfiguration webMergedConfig) {
100176
}
101177

102178
/**
103-
* TODO [SPR-9864] Document loadBeanDefinitions().
179+
* Load bean definitions into the supplied {@link GenericWebApplicationContext context}
180+
* from the locations or classes in the supplied <code>WebMergedContextConfiguration</code>.
181+
*
182+
* <p>Concrete subclasses must provide an appropriate implementation.
183+
*
184+
* @param context the context into which the bean definitions should be loaded
185+
* @param webMergedConfig the merged context configuration to use to load the
186+
* web application context
187+
* @see #loadContext(MergedContextConfiguration)
104188
*/
105189
protected abstract void loadBeanDefinitions(GenericWebApplicationContext context,
106190
WebMergedContextConfiguration webMergedConfig);
107191

108192
/**
109-
* TODO [SPR-9864] Document customizeContext().
193+
* Customize the {@link GenericWebApplicationContext} created by this context
194+
* loader <i>after</i> bean definitions have been loaded into the context but
195+
* <i>before</i> the context is refreshed.
196+
*
197+
* <p>The default implementation is empty but can be overridden in subclasses
198+
* to customize the web application context.
199+
*
200+
* @param context the newly created web application context
201+
* @param webMergedConfig the merged context configuration to use to load the
202+
* web application context
203+
* @see #loadContext(MergedContextConfiguration)
110204
*/
111205
protected void customizeContext(GenericWebApplicationContext context, WebMergedContextConfiguration webMergedConfig) {
112206
}
113207

114208
// --- ContextLoader -------------------------------------------------------
115209

116210
/**
117-
* TODO [SPR-9864] Document overridden loadContext(String...).
211+
* {@code AbstractGenericWebContextLoader} should be used as a
212+
* {@link org.springframework.test.context.SmartContextLoader SmartContextLoader},
213+
* not as a legacy {@link org.springframework.test.context.ContextLoader ContextLoader}.
214+
* Consequently, this method is not supported.
118215
*
119216
* @see org.springframework.test.context.ContextLoader#loadContext(java.lang.String[])
217+
* @throws UnsupportedOperationException
120218
*/
121219
public final ApplicationContext loadContext(String... locations) throws Exception {
122220
throw new UnsupportedOperationException(

spring-test/src/main/java/org/springframework/test/context/web/AnnotationConfigWebContextLoader.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,38 @@
1818

1919
import org.apache.commons.logging.Log;
2020
import org.apache.commons.logging.LogFactory;
21+
2122
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
2223
import org.springframework.test.context.ContextConfigurationAttributes;
23-
import org.springframework.test.context.support.AbstractContextLoader;
2424
import org.springframework.test.context.support.AnnotationConfigContextLoaderUtils;
2525
import org.springframework.util.ObjectUtils;
2626
import org.springframework.web.context.support.GenericWebApplicationContext;
2727

2828
/**
29-
* TODO [SPR-9864] Document AnnotationConfigWebContextLoader.
29+
* Concrete implementation of {@link AbstractGenericWebContextLoader} that loads
30+
* bean definitions from annotated classes.
31+
*
32+
* <p>See the Javadoc for
33+
* {@link org.springframework.test.context.ContextConfiguration @ContextConfiguration}
34+
* for a definition of <em>annotated class</em>.
35+
*
36+
* <p>Note: <code>AnnotationConfigWebContextLoader</code> supports <em>annotated classes</em>
37+
* rather than the String-based resource locations defined by the legacy
38+
* {@link org.springframework.test.context.ContextLoader ContextLoader} API. Thus,
39+
* although <code>AnnotationConfigWebContextLoader</code> extends
40+
* <code>AbstractGenericWebContextLoader</code>, <code>AnnotationConfigWebContextLoader</code>
41+
* does <em>not</em> support any String-based methods defined by
42+
* {@link org.springframework.test.context.support.AbstractContextLoader
43+
* AbstractContextLoader} or <code>AbstractGenericWebContextLoader</code>.
44+
* Consequently, <code>AnnotationConfigWebContextLoader</code> should chiefly be
45+
* considered a {@link org.springframework.test.context.SmartContextLoader SmartContextLoader}
46+
* rather than a {@link org.springframework.test.context.ContextLoader ContextLoader}.
3047
*
3148
* @author Sam Brannen
3249
* @since 3.2
50+
* @see #processContextConfiguration(ContextConfigurationAttributes)
51+
* @see #detectDefaultConfigurationClasses(Class)
52+
* @see #loadBeanDefinitions(GenericWebApplicationContext, WebMergedContextConfiguration)
3353
*/
3454
public class AnnotationConfigWebContextLoader extends AbstractGenericWebContextLoader {
3555

@@ -43,10 +63,10 @@ public class AnnotationConfigWebContextLoader extends AbstractGenericWebContextL
4363
*
4464
* <p>If the <em>annotated classes</em> are <code>null</code> or empty and
4565
* {@link #isGenerateDefaultLocations()} returns <code>true</code>, this
46-
* <code>SmartContextLoader</code> will attempt to {@link
66+
* <code>SmartContextLoader</code> will attempt to {@linkplain
4767
* #detectDefaultConfigurationClasses detect default configuration classes}.
4868
* If defaults are detected they will be
49-
* {@link ContextConfigurationAttributes#setClasses(Class[]) set} in the
69+
* {@linkplain ContextConfigurationAttributes#setClasses(Class[]) set} in the
5070
* supplied configuration attributes. Otherwise, properties in the supplied
5171
* configuration attributes will not be modified.
5272
*
@@ -85,7 +105,7 @@ protected Class<?>[] detectDefaultConfigurationClasses(Class<?> declaringClass)
85105
* not as a legacy {@link org.springframework.test.context.ContextLoader ContextLoader}.
86106
* Consequently, this method is not supported.
87107
*
88-
* @see AbstractContextLoader#modifyLocations
108+
* @see org.springframework.test.context.support.AbstractContextLoader#modifyLocations
89109
* @throws UnsupportedOperationException
90110
*/
91111
@Override
@@ -100,7 +120,7 @@ protected String[] modifyLocations(Class<?> clazz, String... locations) {
100120
* not as a legacy {@link org.springframework.test.context.ContextLoader ContextLoader}.
101121
* Consequently, this method is not supported.
102122
*
103-
* @see AbstractContextLoader#generateDefaultLocations
123+
* @see org.springframework.test.context.support.AbstractContextLoader#generateDefaultLocations
104124
* @throws UnsupportedOperationException
105125
*/
106126
@Override
@@ -115,7 +135,7 @@ protected String[] generateDefaultLocations(Class<?> clazz) {
115135
* not as a legacy {@link org.springframework.test.context.ContextLoader ContextLoader}.
116136
* Consequently, this method is not supported.
117137
*
118-
* @see AbstractContextLoader#getResourceSuffix
138+
* @see org.springframework.test.context.support.AbstractContextLoader#getResourceSuffix
119139
* @throws UnsupportedOperationException
120140
*/
121141
@Override
@@ -127,7 +147,7 @@ protected String getResourceSuffix() {
127147
// --- AbstractGenericWebContextLoader -------------------------------------
128148

129149
/**
130-
* Register classes in the supplied {@link GenericWebApplicationContext context}
150+
* Register classes in the supplied {@linkplain GenericWebApplicationContext context}
131151
* from the classes in the supplied {@link WebMergedContextConfiguration}.
132152
*
133153
* <p>Each class must represent an <em>annotated class</em>. An

spring-test/src/main/java/org/springframework/test/context/web/GenericXmlWebContextLoader.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,18 @@
2020
import org.springframework.web.context.support.GenericWebApplicationContext;
2121

2222
/**
23-
* TODO [SPR-9864] Document GenericXmlWebContextLoader.
23+
* Concrete implementation of {@link AbstractGenericWebContextLoader} that loads
24+
* bean definitions from XML resources.
2425
*
2526
* @author Sam Brannen
2627
* @since 3.2
2728
*/
2829
public class GenericXmlWebContextLoader extends AbstractGenericWebContextLoader {
2930

3031
/**
31-
* TODO [SPR-9864] Document overridden loadBeanDefinitions().
32+
* Loads bean definitions using an {@link XmlBeanDefinitionReader}.
3233
*
33-
* @see org.springframework.test.context.web.AbstractGenericWebContextLoader#loadBeanDefinitions(org.springframework.web.context.support.GenericWebApplicationContext, org.springframework.test.context.web.WebMergedContextConfiguration)
34+
* @see AbstractGenericWebContextLoader#loadBeanDefinitions()
3435
*/
3536
@Override
3637
protected void loadBeanDefinitions(GenericWebApplicationContext context,

spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.commons.logging.Log;
2222
import org.apache.commons.logging.LogFactory;
23+
2324
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2425
import org.springframework.context.ApplicationContext;
2526
import org.springframework.context.ConfigurableApplicationContext;
@@ -34,7 +35,24 @@
3435
import org.springframework.web.context.request.ServletWebRequest;
3536

3637
/**
37-
* TODO [SPR-9864] Document ServletTestExecutionListener.
38+
* {@code TestExecutionListener} which provides mock Servlet API support to
39+
* {@link WebApplicationContext WebApplicationContexts} loaded by the <em>Spring
40+
* TestContext Framework</em>.
41+
*
42+
* <p>Specifically, {@code ServletTestExecutionListener} sets up thread-local
43+
* state via Spring Web's {@link RequestContextHolder} during {@linkplain
44+
* #prepareTestInstance(TestContext) test instance preparation} and {@linkplain
45+
* #beforeTestMethod(TestContext) before each test method} and creates a {@link
46+
* MockHttpServletRequest}, {@link MockHttpServletResponse}, and
47+
* {@link ServletWebRequest} based on the {@link MockServletContext} present in
48+
* the {@code WebApplicationContext}. This listener also ensures that the
49+
* {@code MockHttpServletResponse} and {@code ServletWebRequest} can be injected
50+
* into the test instance, and once the test is complete this listener {@linkplain
51+
* #afterTestMethod(TestContext) cleans up} thread-local state.
52+
*
53+
* <p>Note that {@code ServletTestExecutionListener} is enabled by default but
54+
* takes no action if the {@link ApplicationContext} loaded for the current test
55+
* is not a {@link WebApplicationContext}.
3856
*
3957
* @author Sam Brannen
4058
* @since 3.2
@@ -43,27 +61,33 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
4361

4462
private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class);
4563

46-
64+
4765
/**
48-
* TODO [SPR-9864] Document overridden prepareTestInstance().
66+
* Sets up thread-local state during the <em>test instance preparation</em>
67+
* callback phase via Spring Web's {@link RequestContextHolder}.
4968
*
5069
* @see TestExecutionListener#prepareTestInstance(TestContext)
70+
* @see #setUpRequestContextIfNecessary(TestContext)
5171
*/
5272
public void prepareTestInstance(TestContext testContext) throws Exception {
5373
setUpRequestContextIfNecessary(testContext);
5474
}
5575

5676
/**
57-
* TODO [SPR-9864] Document overridden beforeTestMethod().
77+
* Sets up thread-local state before each test method via Spring Web's
78+
* {@link RequestContextHolder}.
5879
*
5980
* @see TestExecutionListener#beforeTestMethod(TestContext)
81+
* @see #setUpRequestContextIfNecessary(TestContext)
6082
*/
6183
public void beforeTestMethod(TestContext testContext) throws Exception {
6284
setUpRequestContextIfNecessary(testContext);
6385
}
6486

6587
/**
66-
* TODO [SPR-9864] Document overridden afterTestMethod().
88+
* Cleans up thread-local state after each test method by {@linkplain
89+
* RequestContextHolder#resetRequestAttributes() resetting} Spring Web's
90+
* {@code RequestContextHolder}.
6791
*
6892
* @see TestExecutionListener#afterTestMethod(TestContext)
6993
*/
@@ -74,11 +98,6 @@ public void afterTestMethod(TestContext testContext) throws Exception {
7498
RequestContextHolder.resetRequestAttributes();
7599
}
76100

77-
/**
78-
* TODO [SPR-9864] Document setUpRequestContext().
79-
*
80-
* @param testContext
81-
*/
82101
private void setUpRequestContextIfNecessary(TestContext testContext) {
83102

84103
ApplicationContext context = testContext.getApplicationContext();

0 commit comments

Comments
 (0)