|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2012 the original author or authors. |
| 2 | + * Copyright 2002-2013 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
23 | 23 | import java.util.Map;
|
24 | 24 | import java.util.Properties;
|
25 | 25 | import java.util.concurrent.ConcurrentHashMap;
|
26 |
| - |
27 | 26 | import javax.servlet.ServletContext;
|
28 | 27 |
|
29 | 28 | import org.apache.commons.logging.Log;
|
30 | 29 | import org.apache.commons.logging.LogFactory;
|
| 30 | + |
31 | 31 | import org.springframework.beans.BeanUtils;
|
32 | 32 | import org.springframework.beans.factory.access.BeanFactoryLocator;
|
33 | 33 | import org.springframework.beans.factory.access.BeanFactoryReference;
|
|
50 | 50 | * Called by {@link ContextLoaderListener}.
|
51 | 51 | *
|
52 | 52 | * <p>Looks for a {@link #CONTEXT_CLASS_PARAM "contextClass"} parameter
|
53 |
| - * at the <code>web.xml</code> context-param level to specify the context |
| 53 | + * at the {@code web.xml} context-param level to specify the context |
54 | 54 | * class type, falling back to the default of
|
55 | 55 | * {@link org.springframework.web.context.support.XmlWebApplicationContext}
|
56 | 56 | * if not found. With the default ContextLoader implementation, any context class
|
@@ -119,29 +119,29 @@ public class ContextLoader {
|
119 | 119 | public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
|
120 | 120 |
|
121 | 121 | /**
|
122 |
| - * Optional servlet context parameter (i.e., "<code>locatorFactorySelector</code>") |
| 122 | + * Optional servlet context parameter (i.e., "{@code locatorFactorySelector}") |
123 | 123 | * used only when obtaining a parent context using the default implementation
|
124 | 124 | * of {@link #loadParentContext(ServletContext servletContext)}.
|
125 | 125 | * Specifies the 'selector' used in the
|
126 | 126 | * {@link ContextSingletonBeanFactoryLocator#getInstance(String selector)}
|
127 | 127 | * method call, which is used to obtain the BeanFactoryLocator instance from
|
128 | 128 | * which the parent context is obtained.
|
129 |
| - * <p>The default is <code>classpath*:beanRefContext.xml</code>, |
| 129 | + * <p>The default is {@code classpath*:beanRefContext.xml}, |
130 | 130 | * matching the default applied for the
|
131 | 131 | * {@link ContextSingletonBeanFactoryLocator#getInstance()} method.
|
132 | 132 | * Supplying the "parentContextKey" parameter is sufficient in this case.
|
133 | 133 | */
|
134 | 134 | public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
|
135 | 135 |
|
136 | 136 | /**
|
137 |
| - * Optional servlet context parameter (i.e., "<code>parentContextKey</code>") |
| 137 | + * Optional servlet context parameter (i.e., "{@code parentContextKey}") |
138 | 138 | * used only when obtaining a parent context using the default implementation
|
139 | 139 | * of {@link #loadParentContext(ServletContext servletContext)}.
|
140 | 140 | * Specifies the 'factoryKey' used in the
|
141 | 141 | * {@link BeanFactoryLocator#useBeanFactory(String factoryKey)} method call,
|
142 | 142 | * obtaining the parent application context from the BeanFactoryLocator instance.
|
143 | 143 | * <p>Supplying this "parentContextKey" parameter is sufficient when relying
|
144 |
| - * on the default <code>classpath*:beanRefContext.xml</code> selector for |
| 144 | + * on the default {@code classpath*:beanRefContext.xml} selector for |
145 | 145 | * candidate factory references.
|
146 | 146 | */
|
147 | 147 | public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
|
@@ -280,7 +280,18 @@ public WebApplicationContext initWebApplicationContext(ServletContext servletCon
|
280 | 280 | this.context = createWebApplicationContext(servletContext);
|
281 | 281 | }
|
282 | 282 | if (this.context instanceof ConfigurableWebApplicationContext) {
|
283 |
| - configureAndRefreshWebApplicationContext((ConfigurableWebApplicationContext)this.context, servletContext); |
| 283 | + ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context; |
| 284 | + if (!cwac.isActive()) { |
| 285 | + // The context has not yet been refreshed -> provide services such as |
| 286 | + // setting the parent context, setting the application context id, etc |
| 287 | + if (cwac.getParent() == null) { |
| 288 | + // The context instance was injected without an explicit parent -> |
| 289 | + // determine parent for root web application context, if any. |
| 290 | + ApplicationContext parent = loadParentContext(servletContext); |
| 291 | + cwac.setParent(parent); |
| 292 | + } |
| 293 | + configureAndRefreshWebApplicationContext(cwac, servletContext); |
| 294 | + } |
284 | 295 | }
|
285 | 296 | servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
|
286 | 297 |
|
@@ -333,9 +344,7 @@ protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
|
333 | 344 | throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
|
334 | 345 | "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
|
335 | 346 | }
|
336 |
| - ConfigurableWebApplicationContext wac = |
337 |
| - (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); |
338 |
| - return wac; |
| 347 | + return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); |
339 | 348 | }
|
340 | 349 |
|
341 | 350 | /**
|
@@ -370,10 +379,6 @@ protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicati
|
370 | 379 | }
|
371 | 380 | }
|
372 | 381 |
|
373 |
| - // Determine parent for root web application context, if any. |
374 |
| - ApplicationContext parent = loadParentContext(sc); |
375 |
| - |
376 |
| - wac.setParent(parent); |
377 | 382 | wac.setServletContext(sc);
|
378 | 383 | String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM);
|
379 | 384 | if (initParameter != null) {
|
@@ -470,17 +475,18 @@ protected void customizeContext(ServletContext servletContext, ConfigurableWebAp
|
470 | 475 | return;
|
471 | 476 | }
|
472 | 477 |
|
| 478 | + Class<?> contextClass = applicationContext.getClass(); |
473 | 479 | ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances =
|
474 |
| - new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>(); |
| 480 | + new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>(); |
475 | 481 |
|
476 | 482 | for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) {
|
477 |
| - Class<?> contextClass = applicationContext.getClass(); |
478 | 483 | Class<?> initializerContextClass =
|
479 |
| - GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class); |
| 484 | + GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class); |
480 | 485 | Assert.isAssignable(initializerContextClass, contextClass, String.format(
|
481 | 486 | "Could not add context initializer [%s] as its generic parameter [%s] " +
|
482 | 487 | "is not assignable from the type of application context used by this " +
|
483 |
| - "context loader [%s]", initializerClass.getName(), initializerContextClass, contextClass)); |
| 488 | + "context loader [%s]: ", initializerClass.getName(), initializerContextClass.getName(), |
| 489 | + contextClass.getName())); |
484 | 490 | initializerInstances.add(BeanUtils.instantiateClass(initializerClass));
|
485 | 491 | }
|
486 | 492 |
|
@@ -509,7 +515,7 @@ protected void customizeContext(ServletContext servletContext, ConfigurableWebAp
|
509 | 515 | * which will be shared by all other users of ContextsingletonBeanFactoryLocator
|
510 | 516 | * which also use the same configuration parameters.
|
511 | 517 | * @param servletContext current servlet context
|
512 |
| - * @return the parent application context, or <code>null</code> if none |
| 518 | + * @return the parent application context, or {@code null} if none |
513 | 519 | * @see org.springframework.context.access.ContextSingletonBeanFactoryLocator
|
514 | 520 | */
|
515 | 521 | protected ApplicationContext loadParentContext(ServletContext servletContext) {
|
@@ -568,7 +574,7 @@ else if (ccl != null) {
|
568 | 574 | * Obtain the Spring root web application context for the current thread
|
569 | 575 | * (i.e. for the current thread's context ClassLoader, which needs to be
|
570 | 576 | * the web application's ClassLoader).
|
571 |
| - * @return the current root web application context, or <code>null</code> |
| 577 | + * @return the current root web application context, or {@code null} |
572 | 578 | * if none found
|
573 | 579 | * @see org.springframework.web.context.support.SpringBeanAutowiringSupport
|
574 | 580 | */
|
|
0 commit comments