001/*
002 * Copyright 2002-2020 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.context.support;
018
019import java.io.IOException;
020import java.lang.annotation.Annotation;
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.Date;
024import java.util.LinkedHashSet;
025import java.util.List;
026import java.util.Locale;
027import java.util.Map;
028import java.util.Set;
029import java.util.concurrent.atomic.AtomicBoolean;
030
031import org.apache.commons.logging.Log;
032import org.apache.commons.logging.LogFactory;
033
034import org.springframework.beans.BeansException;
035import org.springframework.beans.CachedIntrospectionResults;
036import org.springframework.beans.factory.BeanFactory;
037import org.springframework.beans.factory.NoSuchBeanDefinitionException;
038import org.springframework.beans.factory.ObjectProvider;
039import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
040import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
041import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
042import org.springframework.beans.support.ResourceEditorRegistrar;
043import org.springframework.context.ApplicationContext;
044import org.springframework.context.ApplicationContextAware;
045import org.springframework.context.ApplicationEvent;
046import org.springframework.context.ApplicationEventPublisher;
047import org.springframework.context.ApplicationEventPublisherAware;
048import org.springframework.context.ApplicationListener;
049import org.springframework.context.ConfigurableApplicationContext;
050import org.springframework.context.EmbeddedValueResolverAware;
051import org.springframework.context.EnvironmentAware;
052import org.springframework.context.HierarchicalMessageSource;
053import org.springframework.context.LifecycleProcessor;
054import org.springframework.context.MessageSource;
055import org.springframework.context.MessageSourceAware;
056import org.springframework.context.MessageSourceResolvable;
057import org.springframework.context.NoSuchMessageException;
058import org.springframework.context.PayloadApplicationEvent;
059import org.springframework.context.ResourceLoaderAware;
060import org.springframework.context.event.ApplicationEventMulticaster;
061import org.springframework.context.event.ContextClosedEvent;
062import org.springframework.context.event.ContextRefreshedEvent;
063import org.springframework.context.event.ContextStartedEvent;
064import org.springframework.context.event.ContextStoppedEvent;
065import org.springframework.context.event.SimpleApplicationEventMulticaster;
066import org.springframework.context.expression.StandardBeanExpressionResolver;
067import org.springframework.context.weaving.LoadTimeWeaverAware;
068import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
069import org.springframework.core.ResolvableType;
070import org.springframework.core.annotation.AnnotationUtils;
071import org.springframework.core.convert.ConversionService;
072import org.springframework.core.env.ConfigurableEnvironment;
073import org.springframework.core.env.Environment;
074import org.springframework.core.env.StandardEnvironment;
075import org.springframework.core.io.DefaultResourceLoader;
076import org.springframework.core.io.Resource;
077import org.springframework.core.io.ResourceLoader;
078import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
079import org.springframework.core.io.support.ResourcePatternResolver;
080import org.springframework.lang.Nullable;
081import org.springframework.util.Assert;
082import org.springframework.util.CollectionUtils;
083import org.springframework.util.ObjectUtils;
084import org.springframework.util.ReflectionUtils;
085
086/**
087 * Abstract implementation of the {@link org.springframework.context.ApplicationContext}
088 * interface. Doesn't mandate the type of storage used for configuration; simply
089 * implements common context functionality. Uses the Template Method design pattern,
090 * requiring concrete subclasses to implement abstract methods.
091 *
092 * <p>In contrast to a plain BeanFactory, an ApplicationContext is supposed
093 * to detect special beans defined in its internal bean factory:
094 * Therefore, this class automatically registers
095 * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessors},
096 * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors},
097 * and {@link org.springframework.context.ApplicationListener ApplicationListeners}
098 * which are defined as beans in the context.
099 *
100 * <p>A {@link org.springframework.context.MessageSource} may also be supplied
101 * as a bean in the context, with the name "messageSource"; otherwise, message
102 * resolution is delegated to the parent context. Furthermore, a multicaster
103 * for application events can be supplied as an "applicationEventMulticaster" bean
104 * of type {@link org.springframework.context.event.ApplicationEventMulticaster}
105 * in the context; otherwise, a default multicaster of type
106 * {@link org.springframework.context.event.SimpleApplicationEventMulticaster} will be used.
107 *
108 * <p>Implements resource loading by extending
109 * {@link org.springframework.core.io.DefaultResourceLoader}.
110 * Consequently treats non-URL resource paths as class path resources
111 * (supporting full class path resource names that include the package path,
112 * e.g. "mypackage/myresource.dat"), unless the {@link #getResourceByPath}
113 * method is overridden in a subclass.
114 *
115 * @author Rod Johnson
116 * @author Juergen Hoeller
117 * @author Mark Fisher
118 * @author Stephane Nicoll
119 * @author Sam Brannen
120 * @since January 21, 2001
121 * @see #refreshBeanFactory
122 * @see #getBeanFactory
123 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
124 * @see org.springframework.beans.factory.config.BeanPostProcessor
125 * @see org.springframework.context.event.ApplicationEventMulticaster
126 * @see org.springframework.context.ApplicationListener
127 * @see org.springframework.context.MessageSource
128 */
129public abstract class AbstractApplicationContext extends DefaultResourceLoader
130                implements ConfigurableApplicationContext {
131
132        /**
133         * Name of the MessageSource bean in the factory.
134         * If none is supplied, message resolution is delegated to the parent.
135         * @see MessageSource
136         */
137        public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
138
139        /**
140         * Name of the LifecycleProcessor bean in the factory.
141         * If none is supplied, a DefaultLifecycleProcessor is used.
142         * @see org.springframework.context.LifecycleProcessor
143         * @see org.springframework.context.support.DefaultLifecycleProcessor
144         */
145        public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
146
147        /**
148         * Name of the ApplicationEventMulticaster bean in the factory.
149         * If none is supplied, a default SimpleApplicationEventMulticaster is used.
150         * @see org.springframework.context.event.ApplicationEventMulticaster
151         * @see org.springframework.context.event.SimpleApplicationEventMulticaster
152         */
153        public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
154
155
156        static {
157                // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
158                // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
159                ContextClosedEvent.class.getName();
160        }
161
162
163        /** Logger used by this class. Available to subclasses. */
164        protected final Log logger = LogFactory.getLog(getClass());
165
166        /** Unique id for this context, if any. */
167        private String id = ObjectUtils.identityToString(this);
168
169        /** Display name. */
170        private String displayName = ObjectUtils.identityToString(this);
171
172        /** Parent context. */
173        @Nullable
174        private ApplicationContext parent;
175
176        /** Environment used by this context. */
177        @Nullable
178        private ConfigurableEnvironment environment;
179
180        /** BeanFactoryPostProcessors to apply on refresh. */
181        private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
182
183        /** System time in milliseconds when this context started. */
184        private long startupDate;
185
186        /** Flag that indicates whether this context is currently active. */
187        private final AtomicBoolean active = new AtomicBoolean();
188
189        /** Flag that indicates whether this context has been closed already. */
190        private final AtomicBoolean closed = new AtomicBoolean();
191
192        /** Synchronization monitor for the "refresh" and "destroy". */
193        private final Object startupShutdownMonitor = new Object();
194
195        /** Reference to the JVM shutdown hook, if registered. */
196        @Nullable
197        private Thread shutdownHook;
198
199        /** ResourcePatternResolver used by this context. */
200        private ResourcePatternResolver resourcePatternResolver;
201
202        /** LifecycleProcessor for managing the lifecycle of beans within this context. */
203        @Nullable
204        private LifecycleProcessor lifecycleProcessor;
205
206        /** MessageSource we delegate our implementation of this interface to. */
207        @Nullable
208        private MessageSource messageSource;
209
210        /** Helper class used in event publishing. */
211        @Nullable
212        private ApplicationEventMulticaster applicationEventMulticaster;
213
214        /** Statically specified listeners. */
215        private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
216
217        /** Local listeners registered before refresh. */
218        @Nullable
219        private Set<ApplicationListener<?>> earlyApplicationListeners;
220
221        /** ApplicationEvents published before the multicaster setup. */
222        @Nullable
223        private Set<ApplicationEvent> earlyApplicationEvents;
224
225
226        /**
227         * Create a new AbstractApplicationContext with no parent.
228         */
229        public AbstractApplicationContext() {
230                this.resourcePatternResolver = getResourcePatternResolver();
231        }
232
233        /**
234         * Create a new AbstractApplicationContext with the given parent context.
235         * @param parent the parent context
236         */
237        public AbstractApplicationContext(@Nullable ApplicationContext parent) {
238                this();
239                setParent(parent);
240        }
241
242
243        //---------------------------------------------------------------------
244        // Implementation of ApplicationContext interface
245        //---------------------------------------------------------------------
246
247        /**
248         * Set the unique id of this application context.
249         * <p>Default is the object id of the context instance, or the name
250         * of the context bean if the context is itself defined as a bean.
251         * @param id the unique id of the context
252         */
253        @Override
254        public void setId(String id) {
255                this.id = id;
256        }
257
258        @Override
259        public String getId() {
260                return this.id;
261        }
262
263        @Override
264        public String getApplicationName() {
265                return "";
266        }
267
268        /**
269         * Set a friendly name for this context.
270         * Typically done during initialization of concrete context implementations.
271         * <p>Default is the object id of the context instance.
272         */
273        public void setDisplayName(String displayName) {
274                Assert.hasLength(displayName, "Display name must not be empty");
275                this.displayName = displayName;
276        }
277
278        /**
279         * Return a friendly name for this context.
280         * @return a display name for this context (never {@code null})
281         */
282        @Override
283        public String getDisplayName() {
284                return this.displayName;
285        }
286
287        /**
288         * Return the parent context, or {@code null} if there is no parent
289         * (that is, this context is the root of the context hierarchy).
290         */
291        @Override
292        @Nullable
293        public ApplicationContext getParent() {
294                return this.parent;
295        }
296
297        /**
298         * Set the {@code Environment} for this application context.
299         * <p>Default value is determined by {@link #createEnvironment()}. Replacing the
300         * default with this method is one option but configuration through {@link
301         * #getEnvironment()} should also be considered. In either case, such modifications
302         * should be performed <em>before</em> {@link #refresh()}.
303         * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
304         */
305        @Override
306        public void setEnvironment(ConfigurableEnvironment environment) {
307                this.environment = environment;
308        }
309
310        /**
311         * Return the {@code Environment} for this application context in configurable
312         * form, allowing for further customization.
313         * <p>If none specified, a default environment will be initialized via
314         * {@link #createEnvironment()}.
315         */
316        @Override
317        public ConfigurableEnvironment getEnvironment() {
318                if (this.environment == null) {
319                        this.environment = createEnvironment();
320                }
321                return this.environment;
322        }
323
324        /**
325         * Create and return a new {@link StandardEnvironment}.
326         * <p>Subclasses may override this method in order to supply
327         * a custom {@link ConfigurableEnvironment} implementation.
328         */
329        protected ConfigurableEnvironment createEnvironment() {
330                return new StandardEnvironment();
331        }
332
333        /**
334         * Return this context's internal bean factory as AutowireCapableBeanFactory,
335         * if already available.
336         * @see #getBeanFactory()
337         */
338        @Override
339        public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
340                return getBeanFactory();
341        }
342
343        /**
344         * Return the timestamp (ms) when this context was first loaded.
345         */
346        @Override
347        public long getStartupDate() {
348                return this.startupDate;
349        }
350
351        /**
352         * Publish the given event to all listeners.
353         * <p>Note: Listeners get initialized after the MessageSource, to be able
354         * to access it within listener implementations. Thus, MessageSource
355         * implementations cannot publish events.
356         * @param event the event to publish (may be application-specific or a
357         * standard framework event)
358         */
359        @Override
360        public void publishEvent(ApplicationEvent event) {
361                publishEvent(event, null);
362        }
363
364        /**
365         * Publish the given event to all listeners.
366         * <p>Note: Listeners get initialized after the MessageSource, to be able
367         * to access it within listener implementations. Thus, MessageSource
368         * implementations cannot publish events.
369         * @param event the event to publish (may be an {@link ApplicationEvent}
370         * or a payload object to be turned into a {@link PayloadApplicationEvent})
371         */
372        @Override
373        public void publishEvent(Object event) {
374                publishEvent(event, null);
375        }
376
377        /**
378         * Publish the given event to all listeners.
379         * @param event the event to publish (may be an {@link ApplicationEvent}
380         * or a payload object to be turned into a {@link PayloadApplicationEvent})
381         * @param eventType the resolved event type, if known
382         * @since 4.2
383         */
384        protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
385                Assert.notNull(event, "Event must not be null");
386
387                // Decorate event as an ApplicationEvent if necessary
388                ApplicationEvent applicationEvent;
389                if (event instanceof ApplicationEvent) {
390                        applicationEvent = (ApplicationEvent) event;
391                }
392                else {
393                        applicationEvent = new PayloadApplicationEvent<>(this, event);
394                        if (eventType == null) {
395                                eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
396                        }
397                }
398
399                // Multicast right now if possible - or lazily once the multicaster is initialized
400                if (this.earlyApplicationEvents != null) {
401                        this.earlyApplicationEvents.add(applicationEvent);
402                }
403                else {
404                        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
405                }
406
407                // Publish event via parent context as well...
408                if (this.parent != null) {
409                        if (this.parent instanceof AbstractApplicationContext) {
410                                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
411                        }
412                        else {
413                                this.parent.publishEvent(event);
414                        }
415                }
416        }
417
418        /**
419         * Return the internal ApplicationEventMulticaster used by the context.
420         * @return the internal ApplicationEventMulticaster (never {@code null})
421         * @throws IllegalStateException if the context has not been initialized yet
422         */
423        ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
424                if (this.applicationEventMulticaster == null) {
425                        throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
426                                        "call 'refresh' before multicasting events via the context: " + this);
427                }
428                return this.applicationEventMulticaster;
429        }
430
431        /**
432         * Return the internal LifecycleProcessor used by the context.
433         * @return the internal LifecycleProcessor (never {@code null})
434         * @throws IllegalStateException if the context has not been initialized yet
435         */
436        LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {
437                if (this.lifecycleProcessor == null) {
438                        throw new IllegalStateException("LifecycleProcessor not initialized - " +
439                                        "call 'refresh' before invoking lifecycle methods via the context: " + this);
440                }
441                return this.lifecycleProcessor;
442        }
443
444        /**
445         * Return the ResourcePatternResolver to use for resolving location patterns
446         * into Resource instances. Default is a
447         * {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver},
448         * supporting Ant-style location patterns.
449         * <p>Can be overridden in subclasses, for extended resolution strategies,
450         * for example in a web environment.
451         * <p><b>Do not call this when needing to resolve a location pattern.</b>
452         * Call the context's {@code getResources} method instead, which
453         * will delegate to the ResourcePatternResolver.
454         * @return the ResourcePatternResolver for this context
455         * @see #getResources
456         * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
457         */
458        protected ResourcePatternResolver getResourcePatternResolver() {
459                return new PathMatchingResourcePatternResolver(this);
460        }
461
462
463        //---------------------------------------------------------------------
464        // Implementation of ConfigurableApplicationContext interface
465        //---------------------------------------------------------------------
466
467        /**
468         * Set the parent of this application context.
469         * <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is
470         * {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with
471         * this (child) application context environment if the parent is non-{@code null} and
472         * its environment is an instance of {@link ConfigurableEnvironment}.
473         * @see ConfigurableEnvironment#merge(ConfigurableEnvironment)
474         */
475        @Override
476        public void setParent(@Nullable ApplicationContext parent) {
477                this.parent = parent;
478                if (parent != null) {
479                        Environment parentEnvironment = parent.getEnvironment();
480                        if (parentEnvironment instanceof ConfigurableEnvironment) {
481                                getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
482                        }
483                }
484        }
485
486        @Override
487        public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
488                Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
489                this.beanFactoryPostProcessors.add(postProcessor);
490        }
491
492        /**
493         * Return the list of BeanFactoryPostProcessors that will get applied
494         * to the internal BeanFactory.
495         */
496        public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
497                return this.beanFactoryPostProcessors;
498        }
499
500        @Override
501        public void addApplicationListener(ApplicationListener<?> listener) {
502                Assert.notNull(listener, "ApplicationListener must not be null");
503                if (this.applicationEventMulticaster != null) {
504                        this.applicationEventMulticaster.addApplicationListener(listener);
505                }
506                this.applicationListeners.add(listener);
507        }
508
509        /**
510         * Return the list of statically specified ApplicationListeners.
511         */
512        public Collection<ApplicationListener<?>> getApplicationListeners() {
513                return this.applicationListeners;
514        }
515
516        @Override
517        public void refresh() throws BeansException, IllegalStateException {
518                synchronized (this.startupShutdownMonitor) {
519                        // Prepare this context for refreshing.
520                        prepareRefresh();
521
522                        // Tell the subclass to refresh the internal bean factory.
523                        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
524
525                        // Prepare the bean factory for use in this context.
526                        prepareBeanFactory(beanFactory);
527
528                        try {
529                                // Allows post-processing of the bean factory in context subclasses.
530                                postProcessBeanFactory(beanFactory);
531
532                                // Invoke factory processors registered as beans in the context.
533                                invokeBeanFactoryPostProcessors(beanFactory);
534
535                                // Register bean processors that intercept bean creation.
536                                registerBeanPostProcessors(beanFactory);
537
538                                // Initialize message source for this context.
539                                initMessageSource();
540
541                                // Initialize event multicaster for this context.
542                                initApplicationEventMulticaster();
543
544                                // Initialize other special beans in specific context subclasses.
545                                onRefresh();
546
547                                // Check for listener beans and register them.
548                                registerListeners();
549
550                                // Instantiate all remaining (non-lazy-init) singletons.
551                                finishBeanFactoryInitialization(beanFactory);
552
553                                // Last step: publish corresponding event.
554                                finishRefresh();
555                        }
556
557                        catch (BeansException ex) {
558                                if (logger.isWarnEnabled()) {
559                                        logger.warn("Exception encountered during context initialization - " +
560                                                        "cancelling refresh attempt: " + ex);
561                                }
562
563                                // Destroy already created singletons to avoid dangling resources.
564                                destroyBeans();
565
566                                // Reset 'active' flag.
567                                cancelRefresh(ex);
568
569                                // Propagate exception to caller.
570                                throw ex;
571                        }
572
573                        finally {
574                                // Reset common introspection caches in Spring's core, since we
575                                // might not ever need metadata for singleton beans anymore...
576                                resetCommonCaches();
577                        }
578                }
579        }
580
581        /**
582         * Prepare this context for refreshing, setting its startup date and
583         * active flag as well as performing any initialization of property sources.
584         */
585        protected void prepareRefresh() {
586                // Switch to active.
587                this.startupDate = System.currentTimeMillis();
588                this.closed.set(false);
589                this.active.set(true);
590
591                if (logger.isDebugEnabled()) {
592                        if (logger.isTraceEnabled()) {
593                                logger.trace("Refreshing " + this);
594                        }
595                        else {
596                                logger.debug("Refreshing " + getDisplayName());
597                        }
598                }
599
600                // Initialize any placeholder property sources in the context environment.
601                initPropertySources();
602
603                // Validate that all properties marked as required are resolvable:
604                // see ConfigurablePropertyResolver#setRequiredProperties
605                getEnvironment().validateRequiredProperties();
606
607                // Store pre-refresh ApplicationListeners...
608                if (this.earlyApplicationListeners == null) {
609                        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
610                }
611                else {
612                        // Reset local application listeners to pre-refresh state.
613                        this.applicationListeners.clear();
614                        this.applicationListeners.addAll(this.earlyApplicationListeners);
615                }
616
617                // Allow for the collection of early ApplicationEvents,
618                // to be published once the multicaster is available...
619                this.earlyApplicationEvents = new LinkedHashSet<>();
620        }
621
622        /**
623         * <p>Replace any stub property sources with actual instances.
624         * @see org.springframework.core.env.PropertySource.StubPropertySource
625         * @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
626         */
627        protected void initPropertySources() {
628                // For subclasses: do nothing by default.
629        }
630
631        /**
632         * Tell the subclass to refresh the internal bean factory.
633         * @return the fresh BeanFactory instance
634         * @see #refreshBeanFactory()
635         * @see #getBeanFactory()
636         */
637        protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
638                refreshBeanFactory();
639                return getBeanFactory();
640        }
641
642        /**
643         * Configure the factory's standard context characteristics,
644         * such as the context's ClassLoader and post-processors.
645         * @param beanFactory the BeanFactory to configure
646         */
647        protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
648                // Tell the internal bean factory to use the context's class loader etc.
649                beanFactory.setBeanClassLoader(getClassLoader());
650                beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
651                beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
652
653                // Configure the bean factory with context callbacks.
654                beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
655                beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
656                beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
657                beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
658                beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
659                beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
660                beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
661
662                // BeanFactory interface not registered as resolvable type in a plain factory.
663                // MessageSource registered (and found for autowiring) as a bean.
664                beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
665                beanFactory.registerResolvableDependency(ResourceLoader.class, this);
666                beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
667                beanFactory.registerResolvableDependency(ApplicationContext.class, this);
668
669                // Register early post-processor for detecting inner beans as ApplicationListeners.
670                beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
671
672                // Detect a LoadTimeWeaver and prepare for weaving, if found.
673                if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
674                        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
675                        // Set a temporary ClassLoader for type matching.
676                        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
677                }
678
679                // Register default environment beans.
680                if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
681                        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
682                }
683                if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
684                        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
685                }
686                if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
687                        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
688                }
689        }
690
691        /**
692         * Modify the application context's internal bean factory after its standard
693         * initialization. All bean definitions will have been loaded, but no beans
694         * will have been instantiated yet. This allows for registering special
695         * BeanPostProcessors etc in certain ApplicationContext implementations.
696         * @param beanFactory the bean factory used by the application context
697         */
698        protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
699        }
700
701        /**
702         * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
703         * respecting explicit order if given.
704         * <p>Must be called before singleton instantiation.
705         */
706        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
707                PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
708
709                // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
710                // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
711                if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
712                        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
713                        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
714                }
715        }
716
717        /**
718         * Instantiate and register all BeanPostProcessor beans,
719         * respecting explicit order if given.
720         * <p>Must be called before any instantiation of application beans.
721         */
722        protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
723                PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
724        }
725
726        /**
727         * Initialize the MessageSource.
728         * Use parent's if none defined in this context.
729         */
730        protected void initMessageSource() {
731                ConfigurableListableBeanFactory beanFactory = getBeanFactory();
732                if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
733                        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
734                        // Make MessageSource aware of parent MessageSource.
735                        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
736                                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
737                                if (hms.getParentMessageSource() == null) {
738                                        // Only set parent context as parent MessageSource if no parent MessageSource
739                                        // registered already.
740                                        hms.setParentMessageSource(getInternalParentMessageSource());
741                                }
742                        }
743                        if (logger.isTraceEnabled()) {
744                                logger.trace("Using MessageSource [" + this.messageSource + "]");
745                        }
746                }
747                else {
748                        // Use empty MessageSource to be able to accept getMessage calls.
749                        DelegatingMessageSource dms = new DelegatingMessageSource();
750                        dms.setParentMessageSource(getInternalParentMessageSource());
751                        this.messageSource = dms;
752                        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
753                        if (logger.isTraceEnabled()) {
754                                logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
755                        }
756                }
757        }
758
759        /**
760         * Initialize the ApplicationEventMulticaster.
761         * Uses SimpleApplicationEventMulticaster if none defined in the context.
762         * @see org.springframework.context.event.SimpleApplicationEventMulticaster
763         */
764        protected void initApplicationEventMulticaster() {
765                ConfigurableListableBeanFactory beanFactory = getBeanFactory();
766                if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
767                        this.applicationEventMulticaster =
768                                        beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
769                        if (logger.isTraceEnabled()) {
770                                logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
771                        }
772                }
773                else {
774                        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
775                        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
776                        if (logger.isTraceEnabled()) {
777                                logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
778                                                "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
779                        }
780                }
781        }
782
783        /**
784         * Initialize the LifecycleProcessor.
785         * Uses DefaultLifecycleProcessor if none defined in the context.
786         * @see org.springframework.context.support.DefaultLifecycleProcessor
787         */
788        protected void initLifecycleProcessor() {
789                ConfigurableListableBeanFactory beanFactory = getBeanFactory();
790                if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
791                        this.lifecycleProcessor =
792                                        beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
793                        if (logger.isTraceEnabled()) {
794                                logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
795                        }
796                }
797                else {
798                        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
799                        defaultProcessor.setBeanFactory(beanFactory);
800                        this.lifecycleProcessor = defaultProcessor;
801                        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
802                        if (logger.isTraceEnabled()) {
803                                logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
804                                                "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
805                        }
806                }
807        }
808
809        /**
810         * Template method which can be overridden to add context-specific refresh work.
811         * Called on initialization of special beans, before instantiation of singletons.
812         * <p>This implementation is empty.
813         * @throws BeansException in case of errors
814         * @see #refresh()
815         */
816        protected void onRefresh() throws BeansException {
817                // For subclasses: do nothing by default.
818        }
819
820        /**
821         * Add beans that implement ApplicationListener as listeners.
822         * Doesn't affect other listeners, which can be added without being beans.
823         */
824        protected void registerListeners() {
825                // Register statically specified listeners first.
826                for (ApplicationListener<?> listener : getApplicationListeners()) {
827                        getApplicationEventMulticaster().addApplicationListener(listener);
828                }
829
830                // Do not initialize FactoryBeans here: We need to leave all regular beans
831                // uninitialized to let post-processors apply to them!
832                String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
833                for (String listenerBeanName : listenerBeanNames) {
834                        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
835                }
836
837                // Publish early application events now that we finally have a multicaster...
838                Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
839                this.earlyApplicationEvents = null;
840                if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
841                        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
842                                getApplicationEventMulticaster().multicastEvent(earlyEvent);
843                        }
844                }
845        }
846
847        /**
848         * Finish the initialization of this context's bean factory,
849         * initializing all remaining singleton beans.
850         */
851        protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
852                // Initialize conversion service for this context.
853                if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
854                                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
855                        beanFactory.setConversionService(
856                                        beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
857                }
858
859                // Register a default embedded value resolver if no bean post-processor
860                // (such as a PropertyPlaceholderConfigurer bean) registered any before:
861                // at this point, primarily for resolution in annotation attribute values.
862                if (!beanFactory.hasEmbeddedValueResolver()) {
863                        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
864                }
865
866                // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
867                String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
868                for (String weaverAwareName : weaverAwareNames) {
869                        getBean(weaverAwareName);
870                }
871
872                // Stop using the temporary ClassLoader for type matching.
873                beanFactory.setTempClassLoader(null);
874
875                // Allow for caching all bean definition metadata, not expecting further changes.
876                beanFactory.freezeConfiguration();
877
878                // Instantiate all remaining (non-lazy-init) singletons.
879                beanFactory.preInstantiateSingletons();
880        }
881
882        /**
883         * Finish the refresh of this context, invoking the LifecycleProcessor's
884         * onRefresh() method and publishing the
885         * {@link org.springframework.context.event.ContextRefreshedEvent}.
886         */
887        protected void finishRefresh() {
888                // Clear context-level resource caches (such as ASM metadata from scanning).
889                clearResourceCaches();
890
891                // Initialize lifecycle processor for this context.
892                initLifecycleProcessor();
893
894                // Propagate refresh to lifecycle processor first.
895                getLifecycleProcessor().onRefresh();
896
897                // Publish the final event.
898                publishEvent(new ContextRefreshedEvent(this));
899
900                // Participate in LiveBeansView MBean, if active.
901                LiveBeansView.registerApplicationContext(this);
902        }
903
904        /**
905         * Cancel this context's refresh attempt, resetting the {@code active} flag
906         * after an exception got thrown.
907         * @param ex the exception that led to the cancellation
908         */
909        protected void cancelRefresh(BeansException ex) {
910                this.active.set(false);
911        }
912
913        /**
914         * Reset Spring's common reflection metadata caches, in particular the
915         * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
916         * and {@link CachedIntrospectionResults} caches.
917         * @since 4.2
918         * @see ReflectionUtils#clearCache()
919         * @see AnnotationUtils#clearCache()
920         * @see ResolvableType#clearCache()
921         * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
922         */
923        protected void resetCommonCaches() {
924                ReflectionUtils.clearCache();
925                AnnotationUtils.clearCache();
926                ResolvableType.clearCache();
927                CachedIntrospectionResults.clearClassLoader(getClassLoader());
928        }
929
930
931        /**
932         * Register a shutdown hook {@linkplain Thread#getName() named}
933         * {@code SpringContextShutdownHook} with the JVM runtime, closing this
934         * context on JVM shutdown unless it has already been closed at that time.
935         * <p>Delegates to {@code doClose()} for the actual closing procedure.
936         * @see Runtime#addShutdownHook
937         * @see ConfigurableApplicationContext#SHUTDOWN_HOOK_THREAD_NAME
938         * @see #close()
939         * @see #doClose()
940         */
941        @Override
942        public void registerShutdownHook() {
943                if (this.shutdownHook == null) {
944                        // No shutdown hook registered yet.
945                        this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
946                                @Override
947                                public void run() {
948                                        synchronized (startupShutdownMonitor) {
949                                                doClose();
950                                        }
951                                }
952                        };
953                        Runtime.getRuntime().addShutdownHook(this.shutdownHook);
954                }
955        }
956
957        /**
958         * Callback for destruction of this instance, originally attached
959         * to a {@code DisposableBean} implementation (not anymore in 5.0).
960         * <p>The {@link #close()} method is the native way to shut down
961         * an ApplicationContext, which this method simply delegates to.
962         * @deprecated as of Spring Framework 5.0, in favor of {@link #close()}
963         */
964        @Deprecated
965        public void destroy() {
966                close();
967        }
968
969        /**
970         * Close this application context, destroying all beans in its bean factory.
971         * <p>Delegates to {@code doClose()} for the actual closing procedure.
972         * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
973         * @see #doClose()
974         * @see #registerShutdownHook()
975         */
976        @Override
977        public void close() {
978                synchronized (this.startupShutdownMonitor) {
979                        doClose();
980                        // If we registered a JVM shutdown hook, we don't need it anymore now:
981                        // We've already explicitly closed the context.
982                        if (this.shutdownHook != null) {
983                                try {
984                                        Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
985                                }
986                                catch (IllegalStateException ex) {
987                                        // ignore - VM is already shutting down
988                                }
989                        }
990                }
991        }
992
993        /**
994         * Actually performs context closing: publishes a ContextClosedEvent and
995         * destroys the singletons in the bean factory of this application context.
996         * <p>Called by both {@code close()} and a JVM shutdown hook, if any.
997         * @see org.springframework.context.event.ContextClosedEvent
998         * @see #destroyBeans()
999         * @see #close()
1000         * @see #registerShutdownHook()
1001         */
1002        protected void doClose() {
1003                // Check whether an actual close attempt is necessary...
1004                if (this.active.get() && this.closed.compareAndSet(false, true)) {
1005                        if (logger.isDebugEnabled()) {
1006                                logger.debug("Closing " + this);
1007                        }
1008
1009                        LiveBeansView.unregisterApplicationContext(this);
1010
1011                        try {
1012                                // Publish shutdown event.
1013                                publishEvent(new ContextClosedEvent(this));
1014                        }
1015                        catch (Throwable ex) {
1016                                logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
1017                        }
1018
1019                        // Stop all Lifecycle beans, to avoid delays during individual destruction.
1020                        if (this.lifecycleProcessor != null) {
1021                                try {
1022                                        this.lifecycleProcessor.onClose();
1023                                }
1024                                catch (Throwable ex) {
1025                                        logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
1026                                }
1027                        }
1028
1029                        // Destroy all cached singletons in the context's BeanFactory.
1030                        destroyBeans();
1031
1032                        // Close the state of this context itself.
1033                        closeBeanFactory();
1034
1035                        // Let subclasses do some final clean-up if they wish...
1036                        onClose();
1037
1038                        // Reset local application listeners to pre-refresh state.
1039                        if (this.earlyApplicationListeners != null) {
1040                                this.applicationListeners.clear();
1041                                this.applicationListeners.addAll(this.earlyApplicationListeners);
1042                        }
1043
1044                        // Switch to inactive.
1045                        this.active.set(false);
1046                }
1047        }
1048
1049        /**
1050         * Template method for destroying all beans that this context manages.
1051         * The default implementation destroy all cached singletons in this context,
1052         * invoking {@code DisposableBean.destroy()} and/or the specified
1053         * "destroy-method".
1054         * <p>Can be overridden to add context-specific bean destruction steps
1055         * right before or right after standard singleton destruction,
1056         * while the context's BeanFactory is still active.
1057         * @see #getBeanFactory()
1058         * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
1059         */
1060        protected void destroyBeans() {
1061                getBeanFactory().destroySingletons();
1062        }
1063
1064        /**
1065         * Template method which can be overridden to add context-specific shutdown work.
1066         * The default implementation is empty.
1067         * <p>Called at the end of {@link #doClose}'s shutdown procedure, after
1068         * this context's BeanFactory has been closed. If custom shutdown logic
1069         * needs to execute while the BeanFactory is still active, override
1070         * the {@link #destroyBeans()} method instead.
1071         */
1072        protected void onClose() {
1073                // For subclasses: do nothing by default.
1074        }
1075
1076        @Override
1077        public boolean isActive() {
1078                return this.active.get();
1079        }
1080
1081        /**
1082         * Assert that this context's BeanFactory is currently active,
1083         * throwing an {@link IllegalStateException} if it isn't.
1084         * <p>Invoked by all {@link BeanFactory} delegation methods that depend
1085         * on an active context, i.e. in particular all bean accessor methods.
1086         * <p>The default implementation checks the {@link #isActive() 'active'} status
1087         * of this context overall. May be overridden for more specific checks, or for a
1088         * no-op if {@link #getBeanFactory()} itself throws an exception in such a case.
1089         */
1090        protected void assertBeanFactoryActive() {
1091                if (!this.active.get()) {
1092                        if (this.closed.get()) {
1093                                throw new IllegalStateException(getDisplayName() + " has been closed already");
1094                        }
1095                        else {
1096                                throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
1097                        }
1098                }
1099        }
1100
1101
1102        //---------------------------------------------------------------------
1103        // Implementation of BeanFactory interface
1104        //---------------------------------------------------------------------
1105
1106        @Override
1107        public Object getBean(String name) throws BeansException {
1108                assertBeanFactoryActive();
1109                return getBeanFactory().getBean(name);
1110        }
1111
1112        @Override
1113        public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
1114                assertBeanFactoryActive();
1115                return getBeanFactory().getBean(name, requiredType);
1116        }
1117
1118        @Override
1119        public Object getBean(String name, Object... args) throws BeansException {
1120                assertBeanFactoryActive();
1121                return getBeanFactory().getBean(name, args);
1122        }
1123
1124        @Override
1125        public <T> T getBean(Class<T> requiredType) throws BeansException {
1126                assertBeanFactoryActive();
1127                return getBeanFactory().getBean(requiredType);
1128        }
1129
1130        @Override
1131        public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
1132                assertBeanFactoryActive();
1133                return getBeanFactory().getBean(requiredType, args);
1134        }
1135
1136        @Override
1137        public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {
1138                assertBeanFactoryActive();
1139                return getBeanFactory().getBeanProvider(requiredType);
1140        }
1141
1142        @Override
1143        public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
1144                assertBeanFactoryActive();
1145                return getBeanFactory().getBeanProvider(requiredType);
1146        }
1147
1148        @Override
1149        public boolean containsBean(String name) {
1150                return getBeanFactory().containsBean(name);
1151        }
1152
1153        @Override
1154        public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
1155                assertBeanFactoryActive();
1156                return getBeanFactory().isSingleton(name);
1157        }
1158
1159        @Override
1160        public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
1161                assertBeanFactoryActive();
1162                return getBeanFactory().isPrototype(name);
1163        }
1164
1165        @Override
1166        public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
1167                assertBeanFactoryActive();
1168                return getBeanFactory().isTypeMatch(name, typeToMatch);
1169        }
1170
1171        @Override
1172        public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
1173                assertBeanFactoryActive();
1174                return getBeanFactory().isTypeMatch(name, typeToMatch);
1175        }
1176
1177        @Override
1178        @Nullable
1179        public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
1180                assertBeanFactoryActive();
1181                return getBeanFactory().getType(name);
1182        }
1183
1184        @Override
1185        @Nullable
1186        public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {
1187                assertBeanFactoryActive();
1188                return getBeanFactory().getType(name, allowFactoryBeanInit);
1189        }
1190
1191        @Override
1192        public String[] getAliases(String name) {
1193                return getBeanFactory().getAliases(name);
1194        }
1195
1196
1197        //---------------------------------------------------------------------
1198        // Implementation of ListableBeanFactory interface
1199        //---------------------------------------------------------------------
1200
1201        @Override
1202        public boolean containsBeanDefinition(String beanName) {
1203                return getBeanFactory().containsBeanDefinition(beanName);
1204        }
1205
1206        @Override
1207        public int getBeanDefinitionCount() {
1208                return getBeanFactory().getBeanDefinitionCount();
1209        }
1210
1211        @Override
1212        public String[] getBeanDefinitionNames() {
1213                return getBeanFactory().getBeanDefinitionNames();
1214        }
1215
1216        @Override
1217        public String[] getBeanNamesForType(ResolvableType type) {
1218                assertBeanFactoryActive();
1219                return getBeanFactory().getBeanNamesForType(type);
1220        }
1221
1222        @Override
1223        public String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
1224                assertBeanFactoryActive();
1225                return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
1226        }
1227
1228        @Override
1229        public String[] getBeanNamesForType(@Nullable Class<?> type) {
1230                assertBeanFactoryActive();
1231                return getBeanFactory().getBeanNamesForType(type);
1232        }
1233
1234        @Override
1235        public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
1236                assertBeanFactoryActive();
1237                return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
1238        }
1239
1240        @Override
1241        public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException {
1242                assertBeanFactoryActive();
1243                return getBeanFactory().getBeansOfType(type);
1244        }
1245
1246        @Override
1247        public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
1248                        throws BeansException {
1249
1250                assertBeanFactoryActive();
1251                return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit);
1252        }
1253
1254        @Override
1255        public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
1256                assertBeanFactoryActive();
1257                return getBeanFactory().getBeanNamesForAnnotation(annotationType);
1258        }
1259
1260        @Override
1261        public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
1262                        throws BeansException {
1263
1264                assertBeanFactoryActive();
1265                return getBeanFactory().getBeansWithAnnotation(annotationType);
1266        }
1267
1268        @Override
1269        @Nullable
1270        public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
1271                        throws NoSuchBeanDefinitionException {
1272
1273                assertBeanFactoryActive();
1274                return getBeanFactory().findAnnotationOnBean(beanName, annotationType);
1275        }
1276
1277
1278        //---------------------------------------------------------------------
1279        // Implementation of HierarchicalBeanFactory interface
1280        //---------------------------------------------------------------------
1281
1282        @Override
1283        @Nullable
1284        public BeanFactory getParentBeanFactory() {
1285                return getParent();
1286        }
1287
1288        @Override
1289        public boolean containsLocalBean(String name) {
1290                return getBeanFactory().containsLocalBean(name);
1291        }
1292
1293        /**
1294         * Return the internal bean factory of the parent context if it implements
1295         * ConfigurableApplicationContext; else, return the parent context itself.
1296         * @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
1297         */
1298        @Nullable
1299        protected BeanFactory getInternalParentBeanFactory() {
1300                return (getParent() instanceof ConfigurableApplicationContext ?
1301                                ((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
1302        }
1303
1304
1305        //---------------------------------------------------------------------
1306        // Implementation of MessageSource interface
1307        //---------------------------------------------------------------------
1308
1309        @Override
1310        public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
1311                return getMessageSource().getMessage(code, args, defaultMessage, locale);
1312        }
1313
1314        @Override
1315        public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {
1316                return getMessageSource().getMessage(code, args, locale);
1317        }
1318
1319        @Override
1320        public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
1321                return getMessageSource().getMessage(resolvable, locale);
1322        }
1323
1324        /**
1325         * Return the internal MessageSource used by the context.
1326         * @return the internal MessageSource (never {@code null})
1327         * @throws IllegalStateException if the context has not been initialized yet
1328         */
1329        private MessageSource getMessageSource() throws IllegalStateException {
1330                if (this.messageSource == null) {
1331                        throw new IllegalStateException("MessageSource not initialized - " +
1332                                        "call 'refresh' before accessing messages via the context: " + this);
1333                }
1334                return this.messageSource;
1335        }
1336
1337        /**
1338         * Return the internal message source of the parent context if it is an
1339         * AbstractApplicationContext too; else, return the parent context itself.
1340         */
1341        @Nullable
1342        protected MessageSource getInternalParentMessageSource() {
1343                return (getParent() instanceof AbstractApplicationContext ?
1344                                ((AbstractApplicationContext) getParent()).messageSource : getParent());
1345        }
1346
1347
1348        //---------------------------------------------------------------------
1349        // Implementation of ResourcePatternResolver interface
1350        //---------------------------------------------------------------------
1351
1352        @Override
1353        public Resource[] getResources(String locationPattern) throws IOException {
1354                return this.resourcePatternResolver.getResources(locationPattern);
1355        }
1356
1357
1358        //---------------------------------------------------------------------
1359        // Implementation of Lifecycle interface
1360        //---------------------------------------------------------------------
1361
1362        @Override
1363        public void start() {
1364                getLifecycleProcessor().start();
1365                publishEvent(new ContextStartedEvent(this));
1366        }
1367
1368        @Override
1369        public void stop() {
1370                getLifecycleProcessor().stop();
1371                publishEvent(new ContextStoppedEvent(this));
1372        }
1373
1374        @Override
1375        public boolean isRunning() {
1376                return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
1377        }
1378
1379
1380        //---------------------------------------------------------------------
1381        // Abstract methods that must be implemented by subclasses
1382        //---------------------------------------------------------------------
1383
1384        /**
1385         * Subclasses must implement this method to perform the actual configuration load.
1386         * The method is invoked by {@link #refresh()} before any other initialization work.
1387         * <p>A subclass will either create a new bean factory and hold a reference to it,
1388         * or return a single BeanFactory instance that it holds. In the latter case, it will
1389         * usually throw an IllegalStateException if refreshing the context more than once.
1390         * @throws BeansException if initialization of the bean factory failed
1391         * @throws IllegalStateException if already initialized and multiple refresh
1392         * attempts are not supported
1393         */
1394        protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
1395
1396        /**
1397         * Subclasses must implement this method to release their internal bean factory.
1398         * This method gets invoked by {@link #close()} after all other shutdown work.
1399         * <p>Should never throw an exception but rather log shutdown failures.
1400         */
1401        protected abstract void closeBeanFactory();
1402
1403        /**
1404         * Subclasses must return their internal bean factory here. They should implement the
1405         * lookup efficiently, so that it can be called repeatedly without a performance penalty.
1406         * <p>Note: Subclasses should check whether the context is still active before
1407         * returning the internal bean factory. The internal factory should generally be
1408         * considered unavailable once the context has been closed.
1409         * @return this application context's internal bean factory (never {@code null})
1410         * @throws IllegalStateException if the context does not hold an internal bean factory yet
1411         * (usually if {@link #refresh()} has never been called) or if the context has been
1412         * closed already
1413         * @see #refreshBeanFactory()
1414         * @see #closeBeanFactory()
1415         */
1416        @Override
1417        public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
1418
1419
1420        /**
1421         * Return information about this context.
1422         */
1423        @Override
1424        public String toString() {
1425                StringBuilder sb = new StringBuilder(getDisplayName());
1426                sb.append(", started on ").append(new Date(getStartupDate()));
1427                ApplicationContext parent = getParent();
1428                if (parent != null) {
1429                        sb.append(", parent: ").append(parent.getDisplayName());
1430                }
1431                return sb.toString();
1432        }
1433
1434}