zoukankan      html  css  js  c++  java
  • 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 这个类定义了好多的操作初始化,对于查找各种初始化准备操作很有意义,有空可以多研究一下。
  • 相关阅读:
    bootstrap如何设置每一个选项卡对应一个页面
    SpringBoot集成百度UEditor图片上传后直接访问404解决办法
    从0开始完成SpringBoot+Mybatis实现增删改查
    Luarocks 安装艰难过程
    [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1076)')))
    python + selenium 搭建环境步骤
    mongodb的安装
    git-新建git用户流程-1
    git-关联远程git仓库详细步骤-2
    Django启动服务的流程
  • 原文地址:https://www.cnblogs.com/anyehome/p/12545657.html
Copyright © 2011-2022 走看看