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