AbstractApplicationContext.java 50.8 KB
Newer Older
A
Arjen Poutsma 已提交
1
/*
2
 * Copyright 2002-2019 the original author or authors.
A
Arjen Poutsma 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context.support;

import java.io.IOException;
J
Juergen Hoeller 已提交
20
import java.lang.annotation.Annotation;
A
Arjen Poutsma 已提交
21
import java.util.ArrayList;
22
import java.util.Collection;
A
Arjen Poutsma 已提交
23
import java.util.Date;
24
import java.util.LinkedHashSet;
A
Arjen Poutsma 已提交
25 26 27
import java.util.List;
import java.util.Locale;
import java.util.Map;
28
import java.util.Set;
29
import java.util.concurrent.atomic.AtomicBoolean;
A
Arjen Poutsma 已提交
30 31 32

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
33

A
Arjen Poutsma 已提交
34
import org.springframework.beans.BeansException;
35
import org.springframework.beans.CachedIntrospectionResults;
A
Arjen Poutsma 已提交
36 37
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
38
import org.springframework.beans.factory.ObjectProvider;
A
Arjen Poutsma 已提交
39 40 41 42 43 44 45 46 47 48 49
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.support.ResourceEditorRegistrar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
50
import org.springframework.context.EmbeddedValueResolverAware;
51
import org.springframework.context.EnvironmentAware;
A
Arjen Poutsma 已提交
52
import org.springframework.context.HierarchicalMessageSource;
53
import org.springframework.context.LifecycleProcessor;
A
Arjen Poutsma 已提交
54 55 56 57
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
58
import org.springframework.context.PayloadApplicationEvent;
A
Arjen Poutsma 已提交
59 60 61 62 63 64 65
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
66
import org.springframework.context.expression.StandardBeanExpressionResolver;
67
import org.springframework.context.weaving.LoadTimeWeaverAware;
68
import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
69
import org.springframework.core.ResolvableType;
70
import org.springframework.core.annotation.AnnotationUtils;
71
import org.springframework.core.convert.ConversionService;
72
import org.springframework.core.env.ConfigurableEnvironment;
73
import org.springframework.core.env.Environment;
74
import org.springframework.core.env.StandardEnvironment;
A
Arjen Poutsma 已提交
75 76 77 78 79
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
80
import org.springframework.lang.Nullable;
A
Arjen Poutsma 已提交
81 82
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
83
import org.springframework.util.ReflectionUtils;
A
Arjen Poutsma 已提交
84 85 86 87 88 89 90 91 92 93 94

/**
 * Abstract implementation of the {@link org.springframework.context.ApplicationContext}
 * interface. Doesn't mandate the type of storage used for configuration; simply
 * implements common context functionality. Uses the Template Method design pattern,
 * requiring concrete subclasses to implement abstract methods.
 *
 * <p>In contrast to a plain BeanFactory, an ApplicationContext is supposed
 * to detect special beans defined in its internal bean factory:
 * Therefore, this class automatically registers
 * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessors},
J
Juergen Hoeller 已提交
95
 * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors},
A
Arjen Poutsma 已提交
96 97 98 99 100 101
 * and {@link org.springframework.context.ApplicationListener ApplicationListeners}
 * which are defined as beans in the context.
 *
 * <p>A {@link org.springframework.context.MessageSource} may also be supplied
 * as a bean in the context, with the name "messageSource"; otherwise, message
 * resolution is delegated to the parent context. Furthermore, a multicaster
J
Juergen Hoeller 已提交
102
 * for application events can be supplied as an "applicationEventMulticaster" bean
A
Arjen Poutsma 已提交
103 104 105 106
 * of type {@link org.springframework.context.event.ApplicationEventMulticaster}
 * in the context; otherwise, a default multicaster of type
 * {@link org.springframework.context.event.SimpleApplicationEventMulticaster} will be used.
 *
J
Juergen Hoeller 已提交
107
 * <p>Implements resource loading by extending
A
Arjen Poutsma 已提交
108 109 110 111
 * {@link org.springframework.core.io.DefaultResourceLoader}.
 * Consequently treats non-URL resource paths as class path resources
 * (supporting full class path resource names that include the package path,
 * e.g. "mypackage/myresource.dat"), unless the {@link #getResourceByPath}
J
Juergen Hoeller 已提交
112
 * method is overridden in a subclass.
A
Arjen Poutsma 已提交
113 114 115 116
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Mark Fisher
117
 * @author Stephane Nicoll
A
Arjen Poutsma 已提交
118 119 120 121 122 123 124 125 126 127
 * @since January 21, 2001
 * @see #refreshBeanFactory
 * @see #getBeanFactory
 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
 * @see org.springframework.beans.factory.config.BeanPostProcessor
 * @see org.springframework.context.event.ApplicationEventMulticaster
 * @see org.springframework.context.ApplicationListener
 * @see org.springframework.context.MessageSource
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader
128
		implements ConfigurableApplicationContext {
A
Arjen Poutsma 已提交
129 130 131 132 133 134 135 136

	/**
	 * Name of the MessageSource bean in the factory.
	 * If none is supplied, message resolution is delegated to the parent.
	 * @see MessageSource
	 */
	public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

137 138 139 140 141 142 143 144
	/**
	 * Name of the LifecycleProcessor bean in the factory.
	 * If none is supplied, a DefaultLifecycleProcessor is used.
	 * @see org.springframework.context.LifecycleProcessor
	 * @see org.springframework.context.support.DefaultLifecycleProcessor
	 */
	public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";

A
Arjen Poutsma 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
	/**
	 * Name of the ApplicationEventMulticaster bean in the factory.
	 * If none is supplied, a default SimpleApplicationEventMulticaster is used.
	 * @see org.springframework.context.event.ApplicationEventMulticaster
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";


	static {
		// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
		// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
		ContextClosedEvent.class.getName();
	}


	/** Logger used by this class. Available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

P
Phillip Webb 已提交
164
	/** Unique id for this context, if any. */
A
Arjen Poutsma 已提交
165 166
	private String id = ObjectUtils.identityToString(this);

P
Phillip Webb 已提交
167
	/** Display name. */
168 169
	private String displayName = ObjectUtils.identityToString(this);

P
Phillip Webb 已提交
170
	/** Parent context. */
171
	@Nullable
A
Arjen Poutsma 已提交
172 173
	private ApplicationContext parent;

P
Phillip Webb 已提交
174
	/** Environment used by this context. */
175
	@Nullable
176 177
	private ConfigurableEnvironment environment;

P
Phillip Webb 已提交
178
	/** BeanFactoryPostProcessors to apply on refresh. */
J
Juergen Hoeller 已提交
179
	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
A
Arjen Poutsma 已提交
180

P
Phillip Webb 已提交
181
	/** System time in milliseconds when this context started. */
A
Arjen Poutsma 已提交
182 183
	private long startupDate;

P
Phillip Webb 已提交
184
	/** Flag that indicates whether this context is currently active. */
185
	private final AtomicBoolean active = new AtomicBoolean();
A
Arjen Poutsma 已提交
186

P
Phillip Webb 已提交
187
	/** Flag that indicates whether this context has been closed already. */
188
	private final AtomicBoolean closed = new AtomicBoolean();
A
Arjen Poutsma 已提交
189

P
Phillip Webb 已提交
190
	/** Synchronization monitor for the "refresh" and "destroy". */
A
Arjen Poutsma 已提交
191 192
	private final Object startupShutdownMonitor = new Object();

P
Phillip Webb 已提交
193
	/** Reference to the JVM shutdown hook, if registered. */
194
	@Nullable
A
Arjen Poutsma 已提交
195 196
	private Thread shutdownHook;

P
Phillip Webb 已提交
197
	/** ResourcePatternResolver used by this context. */
A
Arjen Poutsma 已提交
198 199
	private ResourcePatternResolver resourcePatternResolver;

P
Phillip Webb 已提交
200
	/** LifecycleProcessor for managing the lifecycle of beans within this context. */
201
	@Nullable
202 203
	private LifecycleProcessor lifecycleProcessor;

P
Phillip Webb 已提交
204
	/** MessageSource we delegate our implementation of this interface to. */
205
	@Nullable
206 207
	private MessageSource messageSource;

P
Phillip Webb 已提交
208
	/** Helper class used in event publishing. */
209
	@Nullable
A
Arjen Poutsma 已提交
210 211
	private ApplicationEventMulticaster applicationEventMulticaster;

P
Phillip Webb 已提交
212
	/** Statically specified listeners. */
213
	private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
214

215 216 217 218 219
	/** Local listeners registered before refresh. */
	@Nullable
	private Set<ApplicationListener<?>> earlyApplicationListeners;

	/** ApplicationEvents published before the multicaster setup. */
220
	@Nullable
221
	private Set<ApplicationEvent> earlyApplicationEvents;
A
Arjen Poutsma 已提交
222 223 224 225 226 227


	/**
	 * Create a new AbstractApplicationContext with no parent.
	 */
	public AbstractApplicationContext() {
228
		this.resourcePatternResolver = getResourcePatternResolver();
A
Arjen Poutsma 已提交
229 230 231 232 233 234
	}

	/**
	 * Create a new AbstractApplicationContext with the given parent context.
	 * @param parent the parent context
	 */
235
	public AbstractApplicationContext(@Nullable ApplicationContext parent) {
236 237
		this();
		setParent(parent);
A
Arjen Poutsma 已提交
238 239 240 241 242 243 244 245 246 247 248 249 250
	}


	//---------------------------------------------------------------------
	// Implementation of ApplicationContext interface
	//---------------------------------------------------------------------

	/**
	 * Set the unique id of this application context.
	 * <p>Default is the object id of the context instance, or the name
	 * of the context bean if the context is itself defined as a bean.
	 * @param id the unique id of the context
	 */
251
	@Override
A
Arjen Poutsma 已提交
252 253 254 255
	public void setId(String id) {
		this.id = id;
	}

256
	@Override
A
Arjen Poutsma 已提交
257 258 259 260
	public String getId() {
		return this.id;
	}

261
	@Override
262 263 264 265
	public String getApplicationName() {
		return "";
	}

266 267 268 269 270 271 272 273 274 275 276 277
	/**
	 * Set a friendly name for this context.
	 * Typically done during initialization of concrete context implementations.
	 * <p>Default is the object id of the context instance.
	 */
	public void setDisplayName(String displayName) {
		Assert.hasLength(displayName, "Display name must not be empty");
		this.displayName = displayName;
	}

	/**
	 * Return a friendly name for this context.
278
	 * @return a display name for this context (never {@code null})
279
	 */
280
	@Override
281 282 283 284
	public String getDisplayName() {
		return this.displayName;
	}

A
Arjen Poutsma 已提交
285
	/**
286
	 * Return the parent context, or {@code null} if there is no parent
A
Arjen Poutsma 已提交
287 288
	 * (that is, this context is the root of the context hierarchy).
	 */
289
	@Override
290
	@Nullable
A
Arjen Poutsma 已提交
291 292 293 294
	public ApplicationContext getParent() {
		return this.parent;
	}

295
	/**
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
	 * Set the {@code Environment} for this application context.
	 * <p>Default value is determined by {@link #createEnvironment()}. Replacing the
	 * default with this method is one option but configuration through {@link
	 * #getEnvironment()} should also be considered. In either case, such modifications
	 * should be performed <em>before</em> {@link #refresh()}.
	 * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
	 */
	@Override
	public void setEnvironment(ConfigurableEnvironment environment) {
		this.environment = environment;
	}

	/**
	 * Return the {@code Environment} for this application context in configurable
	 * form, allowing for further customization.
	 * <p>If none specified, a default environment will be initialized via
312 313
	 * {@link #createEnvironment()}.
	 */
314
	@Override
315
	public ConfigurableEnvironment getEnvironment() {
316
		if (this.environment == null) {
317
			this.environment = createEnvironment();
318
		}
319 320 321
		return this.environment;
	}

322
	/**
323 324 325
	 * Create and return a new {@link StandardEnvironment}.
	 * <p>Subclasses may override this method in order to supply
	 * a custom {@link ConfigurableEnvironment} implementation.
326
	 */
327 328
	protected ConfigurableEnvironment createEnvironment() {
		return new StandardEnvironment();
329 330
	}

A
Arjen Poutsma 已提交
331 332 333 334 335
	/**
	 * Return this context's internal bean factory as AutowireCapableBeanFactory,
	 * if already available.
	 * @see #getBeanFactory()
	 */
336
	@Override
A
Arjen Poutsma 已提交
337 338 339 340 341 342 343
	public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
		return getBeanFactory();
	}

	/**
	 * Return the timestamp (ms) when this context was first loaded.
	 */
344
	@Override
A
Arjen Poutsma 已提交
345 346 347 348 349 350 351 352 353 354 355 356
	public long getStartupDate() {
		return this.startupDate;
	}

	/**
	 * Publish the given event to all listeners.
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * @param event the event to publish (may be application-specific or a
	 * standard framework event)
	 */
357
	@Override
A
Arjen Poutsma 已提交
358
	public void publishEvent(ApplicationEvent event) {
359 360 361
		publishEvent(event, null);
	}

J
Juergen Hoeller 已提交
362 363 364 365 366 367 368 369
	/**
	 * Publish the given event to all listeners.
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 */
370 371 372 373 374
	@Override
	public void publishEvent(Object event) {
		publishEvent(event, null);
	}

J
Juergen Hoeller 已提交
375 376 377 378 379 380 381
	/**
	 * Publish the given event to all listeners.
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 * @param eventType the resolved event type, if known
	 * @since 4.2
	 */
382
	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
A
Arjen Poutsma 已提交
383
		Assert.notNull(event, "Event must not be null");
384 385 386

		// Decorate event as an ApplicationEvent if necessary
		ApplicationEvent applicationEvent;
387 388 389 390
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}
		else {
391
			applicationEvent = new PayloadApplicationEvent<>(this, event);
392
			if (eventType == null) {
J
Juergen Hoeller 已提交
393
				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
394 395
			}
		}
396 397 398 399 400 401 402 403 404 405

		// Multicast right now if possible - or lazily once the multicaster is initialized
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
A
Arjen Poutsma 已提交
406
		if (this.parent != null) {
407 408 409 410 411 412
			if (this.parent instanceof AbstractApplicationContext) {
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
A
Arjen Poutsma 已提交
413 414 415
		}
	}

416 417
	/**
	 * Return the internal ApplicationEventMulticaster used by the context.
418
	 * @return the internal ApplicationEventMulticaster (never {@code null})
A
Arjen Poutsma 已提交
419 420
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
421
	ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
A
Arjen Poutsma 已提交
422 423 424 425 426 427 428
		if (this.applicationEventMulticaster == null) {
			throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
					"call 'refresh' before multicasting events via the context: " + this);
		}
		return this.applicationEventMulticaster;
	}

429 430
	/**
	 * Return the internal LifecycleProcessor used by the context.
431
	 * @return the internal LifecycleProcessor (never {@code null})
432 433
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
434
	LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {
435 436 437 438 439 440 441
		if (this.lifecycleProcessor == null) {
			throw new IllegalStateException("LifecycleProcessor not initialized - " +
					"call 'refresh' before invoking lifecycle methods via the context: " + this);
		}
		return this.lifecycleProcessor;
	}

A
Arjen Poutsma 已提交
442 443 444 445 446 447 448 449
	/**
	 * Return the ResourcePatternResolver to use for resolving location patterns
	 * into Resource instances. Default is a
	 * {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver},
	 * supporting Ant-style location patterns.
	 * <p>Can be overridden in subclasses, for extended resolution strategies,
	 * for example in a web environment.
	 * <p><b>Do not call this when needing to resolve a location pattern.</b>
450
	 * Call the context's {@code getResources} method instead, which
A
Arjen Poutsma 已提交
451 452 453 454 455 456 457 458 459 460 461 462 463 464
	 * will delegate to the ResourcePatternResolver.
	 * @return the ResourcePatternResolver for this context
	 * @see #getResources
	 * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
	 */
	protected ResourcePatternResolver getResourcePatternResolver() {
		return new PathMatchingResourcePatternResolver(this);
	}


	//---------------------------------------------------------------------
	// Implementation of ConfigurableApplicationContext interface
	//---------------------------------------------------------------------

465
	/**
466
	 * Set the parent of this application context.
467 468 469 470 471
	 * <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is
	 * {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with
	 * this (child) application context environment if the parent is non-{@code null} and
	 * its environment is an instance of {@link ConfigurableEnvironment}.
	 * @see ConfigurableEnvironment#merge(ConfigurableEnvironment)
472
	 */
473
	@Override
474
	public void setParent(@Nullable ApplicationContext parent) {
A
Arjen Poutsma 已提交
475
		this.parent = parent;
476
		if (parent != null) {
477
			Environment parentEnvironment = parent.getEnvironment();
478
			if (parentEnvironment instanceof ConfigurableEnvironment) {
479
				getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
480
			}
481
		}
A
Arjen Poutsma 已提交
482 483
	}

484
	@Override
485 486 487
	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
		this.beanFactoryPostProcessors.add(postProcessor);
A
Arjen Poutsma 已提交
488 489 490 491 492 493
	}

	/**
	 * Return the list of BeanFactoryPostProcessors that will get applied
	 * to the internal BeanFactory.
	 */
494
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
A
Arjen Poutsma 已提交
495 496 497
		return this.beanFactoryPostProcessors;
	}

498
	@Override
499
	public void addApplicationListener(ApplicationListener<?> listener) {
500
		Assert.notNull(listener, "ApplicationListener must not be null");
501 502
		if (this.applicationEventMulticaster != null) {
			this.applicationEventMulticaster.addApplicationListener(listener);
503
		}
504
		this.applicationListeners.add(listener);
A
Arjen Poutsma 已提交
505 506 507 508 509
	}

	/**
	 * Return the list of statically specified ApplicationListeners.
	 */
510
	public Collection<ApplicationListener<?>> getApplicationListeners() {
A
Arjen Poutsma 已提交
511 512 513
		return this.applicationListeners;
	}

514
	@Override
A
Arjen Poutsma 已提交
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
556 557 558 559
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
560

A
Arjen Poutsma 已提交
561
				// Destroy already created singletons to avoid dangling resources.
562
				destroyBeans();
A
Arjen Poutsma 已提交
563 564 565 566 567 568 569

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}
570 571 572 573 574 575

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
A
Arjen Poutsma 已提交
576 577 578 579 580
		}
	}

	/**
	 * Prepare this context for refreshing, setting its startup date and
581
	 * active flag as well as performing any initialization of property sources.
A
Arjen Poutsma 已提交
582 583
	 */
	protected void prepareRefresh() {
584
		// Switch to active.
A
Arjen Poutsma 已提交
585
		this.startupDate = System.currentTimeMillis();
586
		this.closed.set(false);
587
		this.active.set(true);
A
Arjen Poutsma 已提交
588

589
		if (logger.isDebugEnabled()) {
590 591 592 593 594 595
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
A
Arjen Poutsma 已提交
596
		}
597

598
		// Initialize any placeholder property sources in the context environment.
599
		initPropertySources();
600

601
		// Validate that all properties marked as required are resolvable:
602
		// see ConfigurablePropertyResolver#setRequiredProperties
603
		getEnvironment().validateRequiredProperties();
604

605 606 607 608 609 610 611 612 613 614
		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

615 616
		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
617
		this.earlyApplicationEvents = new LinkedHashSet<>();
618 619 620 621 622
	}

	/**
	 * <p>Replace any stub property sources with actual instances.
	 * @see org.springframework.core.env.PropertySource.StubPropertySource
S
Stevo Slavic 已提交
623
	 * @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
624 625 626
	 */
	protected void initPropertySources() {
		// For subclasses: do nothing by default.
A
Arjen Poutsma 已提交
627 628 629 630 631 632 633 634 635 636
	}

	/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
637
		return getBeanFactory();
A
Arjen Poutsma 已提交
638 639 640 641 642 643 644 645
	}

	/**
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 * @param beanFactory the BeanFactory to configure
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
646
		// Tell the internal bean factory to use the context's class loader etc.
A
Arjen Poutsma 已提交
647
		beanFactory.setBeanClassLoader(getClassLoader());
648
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
649
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
A
Arjen Poutsma 已提交
650 651 652

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
653 654
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
A
Arjen Poutsma 已提交
655 656 657 658 659 660 661 662 663 664 665 666
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

667 668 669
		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

A
Arjen Poutsma 已提交
670
		// Detect a LoadTimeWeaver and prepare for weaving, if found.
671 672
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
A
Arjen Poutsma 已提交
673 674 675
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
676 677

		// Register default environment beans.
678
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
679 680
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
681
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
682
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
683
		}
684
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
685
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
686
		}
A
Arjen Poutsma 已提交
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
	}

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for registering special
	 * BeanPostProcessors etc in certain ApplicationContext implementations.
	 * @param beanFactory the bean factory used by the application context
	 */
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
705
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
706 707 708 709 710 711 712

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
A
Arjen Poutsma 已提交
713 714 715
	}

	/**
J
Juergen Hoeller 已提交
716
	 * Instantiate and register all BeanPostProcessor beans,
A
Arjen Poutsma 已提交
717 718 719 720
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
721
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
A
Arjen Poutsma 已提交
722 723 724 725 726 727 728 729 730
	}

	/**
	 * Initialize the MessageSource.
	 * Use parent's if none defined in this context.
	 */
	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
731
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
A
Arjen Poutsma 已提交
732 733 734 735 736 737 738 739 740
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
741 742
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
A
Arjen Poutsma 已提交
743 744 745 746 747 748 749 750
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
751
			if (logger.isTraceEnabled()) {
752
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
A
Arjen Poutsma 已提交
753 754 755 756
			}
		}
	}

757 758 759 760 761 762 763 764 765 766
	/**
	 * Initialize the ApplicationEventMulticaster.
	 * Uses SimpleApplicationEventMulticaster if none defined in the context.
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
767 768
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
769 770 771 772 773
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
774
			if (logger.isTraceEnabled()) {
775 776
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
777 778 779 780
			}
		}
	}

781 782 783 784 785 786 787 788 789 790
	/**
	 * Initialize the LifecycleProcessor.
	 * Uses DefaultLifecycleProcessor if none defined in the context.
	 * @see org.springframework.context.support.DefaultLifecycleProcessor
	 */
	protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
791 792
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
793 794 795 796 797 798 799
			}
		}
		else {
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
800
			if (logger.isTraceEnabled()) {
801 802
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
803 804 805 806
			}
		}
	}

A
Arjen Poutsma 已提交
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
	/**
	 * Template method which can be overridden to add context-specific refresh work.
	 * Called on initialization of special beans, before instantiation of singletons.
	 * <p>This implementation is empty.
	 * @throws BeansException in case of errors
	 * @see #refresh()
	 */
	protected void onRefresh() throws BeansException {
		// For subclasses: do nothing by default.
	}

	/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	protected void registerListeners() {
		// Register statically specified listeners first.
824
		for (ApplicationListener<?> listener : getApplicationListeners()) {
825
			getApplicationEventMulticaster().addApplicationListener(listener);
A
Arjen Poutsma 已提交
826
		}
827

A
Arjen Poutsma 已提交
828 829
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
830
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
831 832 833 834 835 836 837 838 839 840 841
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
A
Arjen Poutsma 已提交
842 843 844 845 846 847 848 849
		}
	}

	/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
850
		// Initialize conversion service for this context.
851 852
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
853 854 855 856
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

857 858 859 860
		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
861
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
862 863
		}

864
		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
865
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
866 867 868 869
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

A
Arjen Poutsma 已提交
870 871 872 873 874 875 876 877 878 879 880
		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

	/**
881 882
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
A
Arjen Poutsma 已提交
883 884 885
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	protected void finishRefresh() {
J
Juergen Hoeller 已提交
886
		// Clear context-level resource caches (such as ASM metadata from scanning).
887 888
		clearResourceCaches();

889 890 891 892 893
		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();
894

J
Juergen Hoeller 已提交
895
		// Publish the final event.
A
Arjen Poutsma 已提交
896
		publishEvent(new ContextRefreshedEvent(this));
897 898 899

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
A
Arjen Poutsma 已提交
900 901 902
	}

	/**
903
	 * Cancel this context's refresh attempt, resetting the {@code active} flag
A
Arjen Poutsma 已提交
904 905 906 907
	 * after an exception got thrown.
	 * @param ex the exception that led to the cancellation
	 */
	protected void cancelRefresh(BeansException ex) {
908
		this.active.set(false);
A
Arjen Poutsma 已提交
909 910
	}

911
	/**
912 913 914
	 * Reset Spring's common reflection metadata caches, in particular the
	 * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
	 * and {@link CachedIntrospectionResults} caches.
915
	 * @since 4.2
916
	 * @see ReflectionUtils#clearCache()
917
	 * @see AnnotationUtils#clearCache()
918 919 920 921
	 * @see ResolvableType#clearCache()
	 * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
	 */
	protected void resetCommonCaches() {
922
		ReflectionUtils.clearCache();
923
		AnnotationUtils.clearCache();
924 925 926 927
		ResolvableType.clearCache();
		CachedIntrospectionResults.clearClassLoader(getClassLoader());
	}

A
Arjen Poutsma 已提交
928 929 930 931

	/**
	 * Register a shutdown hook with the JVM runtime, closing this context
	 * on JVM shutdown unless it has already been closed at that time.
932 933
	 * <p>Delegates to {@code doClose()} for the actual closing procedure.
	 * @see Runtime#addShutdownHook
A
Arjen Poutsma 已提交
934 935 936
	 * @see #close()
	 * @see #doClose()
	 */
937
	@Override
A
Arjen Poutsma 已提交
938 939 940 941
	public void registerShutdownHook() {
		if (this.shutdownHook == null) {
			// No shutdown hook registered yet.
			this.shutdownHook = new Thread() {
942
				@Override
A
Arjen Poutsma 已提交
943
				public void run() {
944 945 946
					synchronized (startupShutdownMonitor) {
						doClose();
					}
A
Arjen Poutsma 已提交
947 948 949 950 951 952 953
				}
			};
			Runtime.getRuntime().addShutdownHook(this.shutdownHook);
		}
	}

	/**
954 955
	 * Callback for destruction of this instance, originally attached
	 * to a {@code DisposableBean} implementation (not anymore in 5.0).
956 957
	 * <p>The {@link #close()} method is the native way to shut down
	 * an ApplicationContext, which this method simply delegates to.
958
	 * @deprecated as of Spring Framework 5.0, in favor of {@link #close()}
A
Arjen Poutsma 已提交
959
	 */
960
	@Deprecated
A
Arjen Poutsma 已提交
961 962 963 964 965 966
	public void destroy() {
		close();
	}

	/**
	 * Close this application context, destroying all beans in its bean factory.
967
	 * <p>Delegates to {@code doClose()} for the actual closing procedure.
A
Arjen Poutsma 已提交
968 969 970 971
	 * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
	 * @see #doClose()
	 * @see #registerShutdownHook()
	 */
972
	@Override
A
Arjen Poutsma 已提交
973 974 975 976 977 978
	public void close() {
		synchronized (this.startupShutdownMonitor) {
			doClose();
			// If we registered a JVM shutdown hook, we don't need it anymore now:
			// We've already explicitly closed the context.
			if (this.shutdownHook != null) {
979 980 981 982 983 984
				try {
					Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
				}
				catch (IllegalStateException ex) {
					// ignore - VM is already shutting down
				}
A
Arjen Poutsma 已提交
985 986 987 988 989 990 991
			}
		}
	}

	/**
	 * Actually performs context closing: publishes a ContextClosedEvent and
	 * destroys the singletons in the bean factory of this application context.
992
	 * <p>Called by both {@code close()} and a JVM shutdown hook, if any.
A
Arjen Poutsma 已提交
993
	 * @see org.springframework.context.event.ContextClosedEvent
994
	 * @see #destroyBeans()
A
Arjen Poutsma 已提交
995 996 997 998
	 * @see #close()
	 * @see #registerShutdownHook()
	 */
	protected void doClose() {
999
		// Check whether an actual close attempt is necessary...
1000
		if (this.active.get() && this.closed.compareAndSet(false, true)) {
1001 1002
			if (logger.isDebugEnabled()) {
				logger.debug("Closing " + this);
A
Arjen Poutsma 已提交
1003
			}
1004

1005 1006
			LiveBeansView.unregisterApplicationContext(this);

A
Arjen Poutsma 已提交
1007 1008 1009 1010 1011
			try {
				// Publish shutdown event.
				publishEvent(new ContextClosedEvent(this));
			}
			catch (Throwable ex) {
1012
				logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
A
Arjen Poutsma 已提交
1013
			}
1014

A
Arjen Poutsma 已提交
1015
			// Stop all Lifecycle beans, to avoid delays during individual destruction.
1016 1017 1018 1019 1020 1021 1022
			if (this.lifecycleProcessor != null) {
				try {
					this.lifecycleProcessor.onClose();
				}
				catch (Throwable ex) {
					logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
				}
1023
			}
1024

A
Arjen Poutsma 已提交
1025 1026
			// Destroy all cached singletons in the context's BeanFactory.
			destroyBeans();
1027

A
Arjen Poutsma 已提交
1028 1029
			// Close the state of this context itself.
			closeBeanFactory();
1030

1031
			// Let subclasses do some final clean-up if they wish...
A
Arjen Poutsma 已提交
1032
			onClose();
1033

1034 1035 1036 1037 1038 1039 1040
			// Reset local application listeners to pre-refresh state.
			if (this.earlyApplicationListeners != null) {
				this.applicationListeners.clear();
				this.applicationListeners.addAll(this.earlyApplicationListeners);
			}

			// Switch to inactive.
1041
			this.active.set(false);
A
Arjen Poutsma 已提交
1042 1043 1044 1045 1046 1047
		}
	}

	/**
	 * Template method for destroying all beans that this context manages.
	 * The default implementation destroy all cached singletons in this context,
1048
	 * invoking {@code DisposableBean.destroy()} and/or the specified
A
Arjen Poutsma 已提交
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
	 * "destroy-method".
	 * <p>Can be overridden to add context-specific bean destruction steps
	 * right before or right after standard singleton destruction,
	 * while the context's BeanFactory is still active.
	 * @see #getBeanFactory()
	 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
	 */
	protected void destroyBeans() {
		getBeanFactory().destroySingletons();
	}

	/**
	 * Template method which can be overridden to add context-specific shutdown work.
	 * The default implementation is empty.
	 * <p>Called at the end of {@link #doClose}'s shutdown procedure, after
	 * this context's BeanFactory has been closed. If custom shutdown logic
	 * needs to execute while the BeanFactory is still active, override
	 * the {@link #destroyBeans()} method instead.
	 */
	protected void onClose() {
		// For subclasses: do nothing by default.
	}

1072
	@Override
A
Arjen Poutsma 已提交
1073
	public boolean isActive() {
1074
		return this.active.get();
A
Arjen Poutsma 已提交
1075 1076
	}

1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
	/**
	 * Assert that this context's BeanFactory is currently active,
	 * throwing an {@link IllegalStateException} if it isn't.
	 * <p>Invoked by all {@link BeanFactory} delegation methods that depend
	 * on an active context, i.e. in particular all bean accessor methods.
	 * <p>The default implementation checks the {@link #isActive() 'active'} status
	 * of this context overall. May be overridden for more specific checks, or for a
	 * no-op if {@link #getBeanFactory()} itself throws an exception in such a case.
	 */
	protected void assertBeanFactoryActive() {
1087 1088 1089 1090 1091 1092
		if (!this.active.get()) {
			if (this.closed.get()) {
				throw new IllegalStateException(getDisplayName() + " has been closed already");
			}
			else {
				throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
1093 1094 1095 1096
			}
		}
	}

A
Arjen Poutsma 已提交
1097 1098 1099 1100 1101

	//---------------------------------------------------------------------
	// Implementation of BeanFactory interface
	//---------------------------------------------------------------------

1102
	@Override
A
Arjen Poutsma 已提交
1103
	public Object getBean(String name) throws BeansException {
1104
		assertBeanFactoryActive();
A
Arjen Poutsma 已提交
1105 1106 1107
		return getBeanFactory().getBean(name);
	}

1108
	@Override
1109
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
1110
		assertBeanFactoryActive();
A
Arjen Poutsma 已提交
1111 1112 1113
		return getBeanFactory().getBean(name, requiredType);
	}

1114
	@Override
1115
	public Object getBean(String name, Object... args) throws BeansException {
1116
		assertBeanFactoryActive();
1117
		return getBeanFactory().getBean(name, args);
1118 1119
	}

1120
	@Override
1121
	public <T> T getBean(Class<T> requiredType) throws BeansException {
1122
		assertBeanFactoryActive();
1123
		return getBeanFactory().getBean(requiredType);
A
Arjen Poutsma 已提交
1124 1125
	}

1126 1127 1128 1129 1130 1131
	@Override
	public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType, args);
	}

1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
	@Override
	public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType);
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType);
	}

1144
	@Override
A
Arjen Poutsma 已提交
1145 1146 1147 1148
	public boolean containsBean(String name) {
		return getBeanFactory().containsBean(name);
	}

1149
	@Override
A
Arjen Poutsma 已提交
1150
	public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
1151
		assertBeanFactoryActive();
A
Arjen Poutsma 已提交
1152 1153 1154
		return getBeanFactory().isSingleton(name);
	}

1155
	@Override
A
Arjen Poutsma 已提交
1156
	public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
1157
		assertBeanFactoryActive();
A
Arjen Poutsma 已提交
1158 1159 1160
		return getBeanFactory().isPrototype(name);
	}

1161
	@Override
1162
	public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
1163
		assertBeanFactoryActive();
1164
		return getBeanFactory().isTypeMatch(name, typeToMatch);
1165 1166
	}

1167
	@Override
1168
	public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
1169
		assertBeanFactoryActive();
1170
		return getBeanFactory().isTypeMatch(name, typeToMatch);
A
Arjen Poutsma 已提交
1171 1172
	}

1173
	@Override
1174
	@Nullable
1175
	public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
1176
		assertBeanFactoryActive();
A
Arjen Poutsma 已提交
1177 1178 1179
		return getBeanFactory().getType(name);
	}

1180
	@Override
A
Arjen Poutsma 已提交
1181 1182 1183 1184 1185 1186 1187 1188 1189
	public String[] getAliases(String name) {
		return getBeanFactory().getAliases(name);
	}


	//---------------------------------------------------------------------
	// Implementation of ListableBeanFactory interface
	//---------------------------------------------------------------------

1190
	@Override
J
Juergen Hoeller 已提交
1191 1192
	public boolean containsBeanDefinition(String beanName) {
		return getBeanFactory().containsBeanDefinition(beanName);
A
Arjen Poutsma 已提交
1193 1194
	}

1195
	@Override
A
Arjen Poutsma 已提交
1196 1197 1198 1199
	public int getBeanDefinitionCount() {
		return getBeanFactory().getBeanDefinitionCount();
	}

1200
	@Override
A
Arjen Poutsma 已提交
1201 1202 1203 1204
	public String[] getBeanDefinitionNames() {
		return getBeanFactory().getBeanDefinitionNames();
	}

1205
	@Override
1206
	public String[] getBeanNamesForType(ResolvableType type) {
1207 1208 1209 1210
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type);
	}

1211
	@Override
1212
	public String[] getBeanNamesForType(@Nullable Class<?> type) {
1213
		assertBeanFactoryActive();
A
Arjen Poutsma 已提交
1214 1215 1216
		return getBeanFactory().getBeanNamesForType(type);
	}

1217
	@Override
1218
	public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
1219
		assertBeanFactoryActive();
1220
		return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
A
Arjen Poutsma 已提交
1221 1222
	}

1223
	@Override
1224
	public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException {
1225
		assertBeanFactoryActive();
A
Arjen Poutsma 已提交
1226 1227 1228
		return getBeanFactory().getBeansOfType(type);
	}

1229
	@Override
1230
	public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
A
Arjen Poutsma 已提交
1231 1232
			throws BeansException {

1233
		assertBeanFactoryActive();
1234
		return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit);
A
Arjen Poutsma 已提交
1235 1236
	}

1237 1238 1239 1240 1241 1242
	@Override
	public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForAnnotation(annotationType);
	}

1243
	@Override
J
Juergen Hoeller 已提交
1244 1245 1246
	public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
			throws BeansException {

1247
		assertBeanFactoryActive();
J
Juergen Hoeller 已提交
1248 1249 1250
		return getBeanFactory().getBeansWithAnnotation(annotationType);
	}

1251
	@Override
1252
	@Nullable
1253
	public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
J
Juergen Hoeller 已提交
1254
			throws NoSuchBeanDefinitionException {
1255

1256
		assertBeanFactoryActive();
J
Juergen Hoeller 已提交
1257 1258 1259
		return getBeanFactory().findAnnotationOnBean(beanName, annotationType);
	}

A
Arjen Poutsma 已提交
1260 1261 1262 1263 1264

	//---------------------------------------------------------------------
	// Implementation of HierarchicalBeanFactory interface
	//---------------------------------------------------------------------

1265
	@Override
1266
	@Nullable
A
Arjen Poutsma 已提交
1267 1268 1269 1270
	public BeanFactory getParentBeanFactory() {
		return getParent();
	}

1271
	@Override
A
Arjen Poutsma 已提交
1272 1273 1274 1275 1276 1277 1278 1279 1280
	public boolean containsLocalBean(String name) {
		return getBeanFactory().containsLocalBean(name);
	}

	/**
	 * Return the internal bean factory of the parent context if it implements
	 * ConfigurableApplicationContext; else, return the parent context itself.
	 * @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
	 */
1281
	@Nullable
A
Arjen Poutsma 已提交
1282
	protected BeanFactory getInternalParentBeanFactory() {
J
Juergen Hoeller 已提交
1283 1284
		return (getParent() instanceof ConfigurableApplicationContext ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
A
Arjen Poutsma 已提交
1285 1286 1287 1288 1289 1290 1291
	}


	//---------------------------------------------------------------------
	// Implementation of MessageSource interface
	//---------------------------------------------------------------------

1292
	@Override
1293
	public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
A
Arjen Poutsma 已提交
1294 1295 1296
		return getMessageSource().getMessage(code, args, defaultMessage, locale);
	}

1297
	@Override
1298
	public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {
A
Arjen Poutsma 已提交
1299 1300 1301
		return getMessageSource().getMessage(code, args, locale);
	}

1302
	@Override
A
Arjen Poutsma 已提交
1303 1304 1305 1306 1307 1308
	public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
		return getMessageSource().getMessage(resolvable, locale);
	}

	/**
	 * Return the internal MessageSource used by the context.
1309
	 * @return the internal MessageSource (never {@code null})
A
Arjen Poutsma 已提交
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	private MessageSource getMessageSource() throws IllegalStateException {
		if (this.messageSource == null) {
			throw new IllegalStateException("MessageSource not initialized - " +
					"call 'refresh' before accessing messages via the context: " + this);
		}
		return this.messageSource;
	}

	/**
	 * Return the internal message source of the parent context if it is an
	 * AbstractApplicationContext too; else, return the parent context itself.
	 */
1324
	@Nullable
A
Arjen Poutsma 已提交
1325
	protected MessageSource getInternalParentMessageSource() {
J
Juergen Hoeller 已提交
1326
		return (getParent() instanceof AbstractApplicationContext ?
1327
				((AbstractApplicationContext) getParent()).messageSource : getParent());
A
Arjen Poutsma 已提交
1328 1329 1330 1331 1332 1333 1334
	}


	//---------------------------------------------------------------------
	// Implementation of ResourcePatternResolver interface
	//---------------------------------------------------------------------

1335
	@Override
A
Arjen Poutsma 已提交
1336 1337 1338 1339 1340 1341 1342 1343 1344
	public Resource[] getResources(String locationPattern) throws IOException {
		return this.resourcePatternResolver.getResources(locationPattern);
	}


	//---------------------------------------------------------------------
	// Implementation of Lifecycle interface
	//---------------------------------------------------------------------

1345
	@Override
A
Arjen Poutsma 已提交
1346
	public void start() {
1347
		getLifecycleProcessor().start();
A
Arjen Poutsma 已提交
1348 1349 1350
		publishEvent(new ContextStartedEvent(this));
	}

1351
	@Override
A
Arjen Poutsma 已提交
1352
	public void stop() {
1353
		getLifecycleProcessor().stop();
A
Arjen Poutsma 已提交
1354 1355 1356
		publishEvent(new ContextStoppedEvent(this));
	}

1357
	@Override
A
Arjen Poutsma 已提交
1358
	public boolean isRunning() {
1359
		return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
A
Arjen Poutsma 已提交
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
	}


	//---------------------------------------------------------------------
	// Abstract methods that must be implemented by subclasses
	//---------------------------------------------------------------------

	/**
	 * Subclasses must implement this method to perform the actual configuration load.
	 * The method is invoked by {@link #refresh()} before any other initialization work.
	 * <p>A subclass will either create a new bean factory and hold a reference to it,
	 * or return a single BeanFactory instance that it holds. In the latter case, it will
	 * usually throw an IllegalStateException if refreshing the context more than once.
	 * @throws BeansException if initialization of the bean factory failed
	 * @throws IllegalStateException if already initialized and multiple refresh
	 * attempts are not supported
	 */
	protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

	/**
	 * Subclasses must implement this method to release their internal bean factory.
	 * This method gets invoked by {@link #close()} after all other shutdown work.
	 * <p>Should never throw an exception but rather log shutdown failures.
	 */
	protected abstract void closeBeanFactory();

	/**
	 * Subclasses must return their internal bean factory here. They should implement the
	 * lookup efficiently, so that it can be called repeatedly without a performance penalty.
	 * <p>Note: Subclasses should check whether the context is still active before
	 * returning the internal bean factory. The internal factory should generally be
	 * considered unavailable once the context has been closed.
1392
	 * @return this application context's internal bean factory (never {@code null})
A
Arjen Poutsma 已提交
1393 1394 1395 1396 1397 1398
	 * @throws IllegalStateException if the context does not hold an internal bean factory yet
	 * (usually if {@link #refresh()} has never been called) or if the context has been
	 * closed already
	 * @see #refreshBeanFactory()
	 * @see #closeBeanFactory()
	 */
1399
	@Override
A
Arjen Poutsma 已提交
1400 1401 1402 1403 1404 1405
	public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;


	/**
	 * Return information about this context.
	 */
1406
	@Override
A
Arjen Poutsma 已提交
1407
	public String toString() {
1408
		StringBuilder sb = new StringBuilder(getDisplayName());
1409
		sb.append(", started on ").append(new Date(getStartupDate()));
A
Arjen Poutsma 已提交
1410
		ApplicationContext parent = getParent();
1411 1412
		if (parent != null) {
			sb.append(", parent: ").append(parent.getDisplayName());
A
Arjen Poutsma 已提交
1413 1414 1415 1416 1417
		}
		return sb.toString();
	}

}