/*
 * Copyright 2002-2019 the original author or authors.
 *
 * 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;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

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

import org.springframework.beans.BeansException;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectProvider;
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;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.LifecycleProcessor;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.PayloadApplicationEvent;
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;
import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
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;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

Abstract implementation of the 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.

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 BeanFactoryPostProcessors, BeanPostProcessors and ApplicationListeners which are defined as beans in the context.

A 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 for application events can be supplied as "applicationEventMulticaster" bean of type ApplicationEventMulticaster in the context; otherwise, a default multicaster of type SimpleApplicationEventMulticaster will be used.

Implements resource loading through extending 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 DefaultResourceLoader.getResourceByPath method is overwritten in a subclass.

Author:Rod Johnson, Juergen Hoeller, Mark Fisher, Stephane Nicoll
See Also:
Since:January 21, 2001
/** * 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}, * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors} * 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 * for application events can be supplied as "applicationEventMulticaster" bean * 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. * * <p>Implements resource loading through extending * {@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} * method is overwritten in a subclass. * * @author Rod Johnson * @author Juergen Hoeller * @author Mark Fisher * @author Stephane Nicoll * @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 implements ConfigurableApplicationContext {
Name of the MessageSource bean in the factory. If none is supplied, message resolution is delegated to the parent.
See Also:
  • MessageSource
/** * 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";
Name of the LifecycleProcessor bean in the factory. If none is supplied, a DefaultLifecycleProcessor is used.
See Also:
/** * 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";
Name of the ApplicationEventMulticaster bean in the factory. If none is supplied, a default SimpleApplicationEventMulticaster is used.
See Also:
/** * 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.
/** Logger used by this class. Available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
Unique id for this context, if any.
/** Unique id for this context, if any. */
private String id = ObjectUtils.identityToString(this);
Display name.
/** Display name. */
private String displayName = ObjectUtils.identityToString(this);
Parent context.
/** Parent context. */
@Nullable private ApplicationContext parent;
Environment used by this context.
/** Environment used by this context. */
@Nullable private ConfigurableEnvironment environment;
BeanFactoryPostProcessors to apply on refresh.
/** BeanFactoryPostProcessors to apply on refresh. */
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
System time in milliseconds when this context started.
/** System time in milliseconds when this context started. */
private long startupDate;
Flag that indicates whether this context is currently active.
/** Flag that indicates whether this context is currently active. */
private final AtomicBoolean active = new AtomicBoolean();
Flag that indicates whether this context has been closed already.
/** Flag that indicates whether this context has been closed already. */
private final AtomicBoolean closed = new AtomicBoolean();
Synchronization monitor for the "refresh" and "destroy".
/** Synchronization monitor for the "refresh" and "destroy". */
private final Object startupShutdownMonitor = new Object();
Reference to the JVM shutdown hook, if registered.
/** Reference to the JVM shutdown hook, if registered. */
@Nullable private Thread shutdownHook;
ResourcePatternResolver used by this context.
/** ResourcePatternResolver used by this context. */
private ResourcePatternResolver resourcePatternResolver;
LifecycleProcessor for managing the lifecycle of beans within this context.
/** LifecycleProcessor for managing the lifecycle of beans within this context. */
@Nullable private LifecycleProcessor lifecycleProcessor;
MessageSource we delegate our implementation of this interface to.
/** MessageSource we delegate our implementation of this interface to. */
@Nullable private MessageSource messageSource;
Helper class used in event publishing.
/** Helper class used in event publishing. */
@Nullable private ApplicationEventMulticaster applicationEventMulticaster;
Statically specified listeners.
/** Statically specified listeners. */
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
Local listeners registered before refresh.
/** Local listeners registered before refresh. */
@Nullable private Set<ApplicationListener<?>> earlyApplicationListeners;
ApplicationEvents published before the multicaster setup.
/** ApplicationEvents published before the multicaster setup. */
@Nullable private Set<ApplicationEvent> earlyApplicationEvents;
Create a new AbstractApplicationContext with no parent.
/** * Create a new AbstractApplicationContext with no parent. */
public AbstractApplicationContext() { this.resourcePatternResolver = getResourcePatternResolver(); }
Create a new AbstractApplicationContext with the given parent context.
Params:
  • parent – the parent context
/** * Create a new AbstractApplicationContext with the given parent context. * @param parent the parent context */
public AbstractApplicationContext(@Nullable ApplicationContext parent) { this(); setParent(parent); } //--------------------------------------------------------------------- // Implementation of ApplicationContext interface //---------------------------------------------------------------------
Set the unique id of this application context.

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.

Params:
  • id – the unique id of the context
/** * 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 */
@Override public void setId(String id) { this.id = id; } @Override public String getId() { return this.id; } @Override public String getApplicationName() { return ""; }
Set a friendly name for this context. Typically done during initialization of concrete context implementations.

Default is the object id of the context instance.

/** * 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.
Returns:a display name for this context (never null)
/** * Return a friendly name for this context. * @return a display name for this context (never {@code null}) */
@Override public String getDisplayName() { return this.displayName; }
Return the parent context, or null if there is no parent (that is, this context is the root of the context hierarchy).
/** * Return the parent context, or {@code null} if there is no parent * (that is, this context is the root of the context hierarchy). */
@Override @Nullable public ApplicationContext getParent() { return this.parent; }
Set the Environment for this application context.

Default value is determined by createEnvironment(). Replacing the default with this method is one option but configuration through getEnvironment() should also be considered. In either case, such modifications should be performed before refresh().

See Also:
/** * 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 Environment for this application context in configurable form, allowing for further customization.

If none specified, a default environment will be initialized via createEnvironment().

/** * 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 * {@link #createEnvironment()}. */
@Override public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = createEnvironment(); } return this.environment; }
Create and return a new StandardEnvironment.

Subclasses may override this method in order to supply a custom ConfigurableEnvironment implementation.

/** * Create and return a new {@link StandardEnvironment}. * <p>Subclasses may override this method in order to supply * a custom {@link ConfigurableEnvironment} implementation. */
protected ConfigurableEnvironment createEnvironment() { return new StandardEnvironment(); }
Return this context's internal bean factory as AutowireCapableBeanFactory, if already available.
See Also:
  • getBeanFactory()
/** * Return this context's internal bean factory as AutowireCapableBeanFactory, * if already available. * @see #getBeanFactory() */
@Override public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException { return getBeanFactory(); }
Return the timestamp (ms) when this context was first loaded.
/** * Return the timestamp (ms) when this context was first loaded. */
@Override public long getStartupDate() { return this.startupDate; }
Publish the given event to all listeners.

Note: Listeners get initialized after the MessageSource, to be able to access it within listener implementations. Thus, MessageSource implementations cannot publish events.

Params:
  • event – the event to publish (may be application-specific or a standard framework event)
/** * 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) */
@Override public void publishEvent(ApplicationEvent event) { publishEvent(event, null); }
Publish the given event to all listeners.

Note: Listeners get initialized after the MessageSource, to be able to access it within listener implementations. Thus, MessageSource implementations cannot publish events.

Params:
/** * 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}) */
@Override public void publishEvent(Object event) { publishEvent(event, null); }
Publish the given event to all listeners.
Params:
Since:4.2
/** * 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 */
protected void publishEvent(Object event, @Nullable ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType(); } } // 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... if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
Return the internal ApplicationEventMulticaster used by the context.
Throws:
Returns:the internal ApplicationEventMulticaster (never null)
/** * Return the internal ApplicationEventMulticaster used by the context. * @return the internal ApplicationEventMulticaster (never {@code null}) * @throws IllegalStateException if the context has not been initialized yet */
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException { if (this.applicationEventMulticaster == null) { throw new IllegalStateException("ApplicationEventMulticaster not initialized - " + "call 'refresh' before multicasting events via the context: " + this); } return this.applicationEventMulticaster; }
Return the internal LifecycleProcessor used by the context.
Throws:
Returns:the internal LifecycleProcessor (never null)
/** * Return the internal LifecycleProcessor used by the context. * @return the internal LifecycleProcessor (never {@code null}) * @throws IllegalStateException if the context has not been initialized yet */
LifecycleProcessor getLifecycleProcessor() throws IllegalStateException { if (this.lifecycleProcessor == null) { throw new IllegalStateException("LifecycleProcessor not initialized - " + "call 'refresh' before invoking lifecycle methods via the context: " + this); } return this.lifecycleProcessor; }
Return the ResourcePatternResolver to use for resolving location patterns into Resource instances. Default is a PathMatchingResourcePatternResolver, supporting Ant-style location patterns.

Can be overridden in subclasses, for extended resolution strategies, for example in a web environment.

Do not call this when needing to resolve a location pattern. Call the context's getResources method instead, which will delegate to the ResourcePatternResolver.

See Also:
Returns:the ResourcePatternResolver for this context
/** * 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> * Call the context's {@code getResources} method instead, which * 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 //---------------------------------------------------------------------
Set the parent of this application context.

The parent environment is merged with this (child) application context environment if the parent is non-null and its environment is an instance of ConfigurableEnvironment.

See Also:
/** * Set the parent of this application context. * <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) */
@Override public void setParent(@Nullable ApplicationContext parent) { this.parent = parent; if (parent != null) { Environment parentEnvironment = parent.getEnvironment(); if (parentEnvironment instanceof ConfigurableEnvironment) { getEnvironment().merge((ConfigurableEnvironment) parentEnvironment); } } } @Override public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) { Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null"); this.beanFactoryPostProcessors.add(postProcessor); }
Return the list of BeanFactoryPostProcessors that will get applied to the internal BeanFactory.
/** * Return the list of BeanFactoryPostProcessors that will get applied * to the internal BeanFactory. */
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; } @Override public void addApplicationListener(ApplicationListener<?> listener) { Assert.notNull(listener, "ApplicationListener must not be null"); if (this.applicationEventMulticaster != null) { this.applicationEventMulticaster.addApplicationListener(listener); } this.applicationListeners.add(listener); }
Return the list of statically specified ApplicationListeners.
/** * Return the list of statically specified ApplicationListeners. */
public Collection<ApplicationListener<?>> getApplicationListeners() { return this.applicationListeners; } @Override 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) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
Prepare this context for refreshing, setting its startup date and active flag as well as performing any initialization of property sources.
/** * Prepare this context for refreshing, setting its startup date and * active flag as well as performing any initialization of property sources. */
protected void prepareRefresh() { // Switch to active. this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } // Initialize any placeholder property sources in the context environment. initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // 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); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }

Replace any stub property sources with actual instances.

See Also:
  • StubPropertySource
  • initServletPropertySources.initServletPropertySources
/** * <p>Replace any stub property sources with actual instances. * @see org.springframework.core.env.PropertySource.StubPropertySource * @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources */
protected void initPropertySources() { // For subclasses: do nothing by default. }
Tell the subclass to refresh the internal bean factory.
See Also:
Returns:the fresh BeanFactory instance
/** * Tell the subclass to refresh the internal bean factory. * @return the fresh BeanFactory instance * @see #refreshBeanFactory() * @see #getBeanFactory() */
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); }
Configure the factory's standard context characteristics, such as the context's ClassLoader and post-processors.
Params:
  • beanFactory – the BeanFactory to configure
/** * 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) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); 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); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
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.
Params:
  • beanFactory – the bean factory used by the application context
/** * 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.

Must be called before singleton instantiation.

/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // 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())); } }
Instantiate and invoke all registered BeanPostProcessor beans, respecting explicit order if given.

Must be called before any instantiation of application beans.

/** * Instantiate and invoke all registered BeanPostProcessor beans, * respecting explicit order if given. * <p>Must be called before any instantiation of application beans. */
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
Initialize the MessageSource. Use parent's if none defined in this context.
/** * 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)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // 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()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } 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); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } } }
Initialize the ApplicationEventMulticaster. Uses SimpleApplicationEventMulticaster if none defined in the context.
See Also:
  • SimpleApplicationEventMulticaster
/** * 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); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]"); } } }
Initialize the LifecycleProcessor. Uses DefaultLifecycleProcessor if none defined in the context.
See Also:
  • DefaultLifecycleProcessor
/** * 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); if (logger.isTraceEnabled()) { logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]"); } } else { DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor(); defaultProcessor.setBeanFactory(beanFactory); this.lifecycleProcessor = defaultProcessor; beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); if (logger.isTraceEnabled()) { logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " + "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]"); } } }
Template method which can be overridden to add context-specific refresh work. Called on initialization of special beans, before instantiation of singletons.

This implementation is empty.

Throws:
  • BeansException – in case of errors
See Also:
/** * 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.
/** * 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. for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); 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); } } }
Finish the initialization of this context's bean factory, initializing all remaining singleton beans.
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // 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()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // 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(); }
Finish the refresh of this context, invoking the LifecycleProcessor's onRefresh() method and publishing the ContextRefreshedEvent.
/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */
protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
Cancel this context's refresh attempt, resetting the active flag after an exception got thrown.
Params:
  • ex – the exception that led to the cancellation
/** * Cancel this context's refresh attempt, resetting the {@code active} flag * after an exception got thrown. * @param ex the exception that led to the cancellation */
protected void cancelRefresh(BeansException ex) { this.active.set(false); }
Reset Spring's common reflection metadata caches, in particular the ReflectionUtils, AnnotationUtils, ResolvableType and CachedIntrospectionResults caches.
See Also:
Since:4.2
/** * Reset Spring's common reflection metadata caches, in particular the * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType} * and {@link CachedIntrospectionResults} caches. * @since 4.2 * @see ReflectionUtils#clearCache() * @see AnnotationUtils#clearCache() * @see ResolvableType#clearCache() * @see CachedIntrospectionResults#clearClassLoader(ClassLoader) */
protected void resetCommonCaches() { ReflectionUtils.clearCache(); AnnotationUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()); }
Register a shutdown hook with the JVM runtime, closing this context on JVM shutdown unless it has already been closed at that time.

Delegates to doClose() for the actual closing procedure.

See Also:
/** * Register a shutdown hook with the JVM runtime, closing this context * on JVM shutdown unless it has already been closed at that time. * <p>Delegates to {@code doClose()} for the actual closing procedure. * @see Runtime#addShutdownHook * @see #close() * @see #doClose() */
@Override public void registerShutdownHook() { if (this.shutdownHook == null) { // No shutdown hook registered yet. this.shutdownHook = new Thread() { @Override public void run() { synchronized (startupShutdownMonitor) { doClose(); } } }; Runtime.getRuntime().addShutdownHook(this.shutdownHook); } }
Callback for destruction of this instance, originally attached to a DisposableBean implementation (not anymore in 5.0).

The close() method is the native way to shut down an ApplicationContext, which this method simply delegates to.

Deprecated:as of Spring Framework 5.0, in favor of close()
/** * Callback for destruction of this instance, originally attached * to a {@code DisposableBean} implementation (not anymore in 5.0). * <p>The {@link #close()} method is the native way to shut down * an ApplicationContext, which this method simply delegates to. * @deprecated as of Spring Framework 5.0, in favor of {@link #close()} */
@Deprecated public void destroy() { close(); }
Close this application context, destroying all beans in its bean factory.

Delegates to doClose() for the actual closing procedure. Also removes a JVM shutdown hook, if registered, as it's not needed anymore.

See Also:
/** * Close this application context, destroying all beans in its bean factory. * <p>Delegates to {@code doClose()} for the actual closing procedure. * Also removes a JVM shutdown hook, if registered, as it's not needed anymore. * @see #doClose() * @see #registerShutdownHook() */
@Override 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) { try { Runtime.getRuntime().removeShutdownHook(this.shutdownHook); } catch (IllegalStateException ex) { // ignore - VM is already shutting down } } } }
Actually performs context closing: publishes a ContextClosedEvent and destroys the singletons in the bean factory of this application context.

Called by both close() and a JVM shutdown hook, if any.

See Also:
/** * Actually performs context closing: publishes a ContextClosedEvent and * destroys the singletons in the bean factory of this application context. * <p>Called by both {@code close()} and a JVM shutdown hook, if any. * @see org.springframework.context.event.ContextClosedEvent * @see #destroyBeans() * @see #close() * @see #registerShutdownHook() */
protected void doClose() { // Check whether an actual close attempt is necessary... if (this.active.get() && this.closed.compareAndSet(false, true)) { if (logger.isDebugEnabled()) { logger.debug("Closing " + this); } LiveBeansView.unregisterApplicationContext(this); try { // Publish shutdown event. publishEvent(new ContextClosedEvent(this)); } catch (Throwable ex) { logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex); } // Stop all Lifecycle beans, to avoid delays during individual destruction. if (this.lifecycleProcessor != null) { try { this.lifecycleProcessor.onClose(); } catch (Throwable ex) { logger.warn("Exception thrown from LifecycleProcessor on context close", ex); } } // Destroy all cached singletons in the context's BeanFactory. destroyBeans(); // Close the state of this context itself. closeBeanFactory(); // Let subclasses do some final clean-up if they wish... onClose(); // Reset local application listeners to pre-refresh state. if (this.earlyApplicationListeners != null) { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Switch to inactive. this.active.set(false); } }
Template method for destroying all beans that this context manages. The default implementation destroy all cached singletons in this context, invoking DisposableBean.destroy() and/or the specified "destroy-method".

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 Also:
/** * Template method for destroying all beans that this context manages. * The default implementation destroy all cached singletons in this context, * invoking {@code DisposableBean.destroy()} and/or the specified * "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.

Called at the end of 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 destroyBeans() method instead.

/** * 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. } @Override public boolean isActive() { return this.active.get(); }
Assert that this context's BeanFactory is currently active, throwing an IllegalStateException if it isn't.

Invoked by all BeanFactory delegation methods that depend on an active context, i.e. in particular all bean accessor methods.

The default implementation checks the 'active' status of this context overall. May be overridden for more specific checks, or for a no-op if getBeanFactory() itself throws an exception in such a case.

/** * 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() { 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"); } } } //--------------------------------------------------------------------- // Implementation of BeanFactory interface //--------------------------------------------------------------------- @Override public Object getBean(String name) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name, requiredType); } @Override public Object getBean(String name, Object... args) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name, args); } @Override public <T> T getBean(Class<T> requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(requiredType); } @Override public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(requiredType, args); } @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); } @Override public boolean containsBean(String name) { return getBeanFactory().containsBean(name); } @Override public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { assertBeanFactoryActive(); return getBeanFactory().isSingleton(name); } @Override public boolean isPrototype(String name) throws NoSuchBeanDefinitionException { assertBeanFactoryActive(); return getBeanFactory().isPrototype(name); } @Override public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException { assertBeanFactoryActive(); return getBeanFactory().isTypeMatch(name, typeToMatch); } @Override public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException { assertBeanFactoryActive(); return getBeanFactory().isTypeMatch(name, typeToMatch); } @Override @Nullable public Class<?> getType(String name) throws NoSuchBeanDefinitionException { assertBeanFactoryActive(); return getBeanFactory().getType(name); } @Override public String[] getAliases(String name) { return getBeanFactory().getAliases(name); } //--------------------------------------------------------------------- // Implementation of ListableBeanFactory interface //--------------------------------------------------------------------- @Override public boolean containsBeanDefinition(String beanName) { return getBeanFactory().containsBeanDefinition(beanName); } @Override public int getBeanDefinitionCount() { return getBeanFactory().getBeanDefinitionCount(); } @Override public String[] getBeanDefinitionNames() { return getBeanFactory().getBeanDefinitionNames(); } @Override public String[] getBeanNamesForType(ResolvableType type) { assertBeanFactoryActive(); return getBeanFactory().getBeanNamesForType(type); } @Override public String[] getBeanNamesForType(@Nullable Class<?> type) { assertBeanFactoryActive(); return getBeanFactory().getBeanNamesForType(type); } @Override public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) { assertBeanFactoryActive(); return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit); } @Override public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBeansOfType(type); } @Override public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit); } @Override public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) { assertBeanFactoryActive(); return getBeanFactory().getBeanNamesForAnnotation(annotationType); } @Override public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBeansWithAnnotation(annotationType); } @Override @Nullable public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) throws NoSuchBeanDefinitionException{ assertBeanFactoryActive(); return getBeanFactory().findAnnotationOnBean(beanName, annotationType); } //--------------------------------------------------------------------- // Implementation of HierarchicalBeanFactory interface //--------------------------------------------------------------------- @Override @Nullable public BeanFactory getParentBeanFactory() { return getParent(); } @Override 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 Also:
  • getBeanFactory.getBeanFactory
/** * 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 */
@Nullable protected BeanFactory getInternalParentBeanFactory() { return (getParent() instanceof ConfigurableApplicationContext ? ((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent()); } //--------------------------------------------------------------------- // Implementation of MessageSource interface //--------------------------------------------------------------------- @Override public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) { return getMessageSource().getMessage(code, args, defaultMessage, locale); } @Override public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException { return getMessageSource().getMessage(code, args, locale); } @Override public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { return getMessageSource().getMessage(resolvable, locale); }
Return the internal MessageSource used by the context.
Throws:
Returns:the internal MessageSource (never null)
/** * Return the internal MessageSource used by the context. * @return the internal MessageSource (never {@code null}) * @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.
/** * Return the internal message source of the parent context if it is an * AbstractApplicationContext too; else, return the parent context itself. */
@Nullable protected MessageSource getInternalParentMessageSource() { return (getParent() instanceof AbstractApplicationContext ? ((AbstractApplicationContext) getParent()).messageSource : getParent()); } //--------------------------------------------------------------------- // Implementation of ResourcePatternResolver interface //--------------------------------------------------------------------- @Override public Resource[] getResources(String locationPattern) throws IOException { return this.resourcePatternResolver.getResources(locationPattern); } //--------------------------------------------------------------------- // Implementation of Lifecycle interface //--------------------------------------------------------------------- @Override public void start() { getLifecycleProcessor().start(); publishEvent(new ContextStartedEvent(this)); } @Override public void stop() { getLifecycleProcessor().stop(); publishEvent(new ContextStoppedEvent(this)); } @Override public boolean isRunning() { return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning()); } //--------------------------------------------------------------------- // Abstract methods that must be implemented by subclasses //---------------------------------------------------------------------
Subclasses must implement this method to perform the actual configuration load. The method is invoked by refresh() before any other initialization work.

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:
/** * 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 close() after all other shutdown work.

Should never throw an exception but rather log shutdown failures.

/** * 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.

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.

Throws:
  • IllegalStateException – if the context does not hold an internal bean factory yet (usually if refresh() has never been called) or if the context has been closed already
See Also:
Returns:this application context's internal bean factory (never null)
/** * 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. * @return this application context's internal bean factory (never {@code null}) * @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() */
@Override public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
Return information about this context.
/** * Return information about this context. */
@Override public String toString() { StringBuilder sb = new StringBuilder(getDisplayName()); sb.append(", started on ").append(new Date(getStartupDate())); ApplicationContext parent = getParent(); if (parent != null) { sb.append(", parent: ").append(parent.getDisplayName()); } return sb.toString(); } }