AbstractApplicationContext 源码

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