📄 abstractapplicationcontext.java
字号:
/*
* Copyright 2002-2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.support;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.core.OrderComparator;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
import org.springframework.core.io.support.ResourcePatternResolver;
/**
* Abstract implementation of the ApplicationContext interface.
* Doesn't mandate the type of storage used for configuration, but implements
* common context functionality. Uses the Template Method design pattern,
* requiring concrete subclasses to implement abstract methods.
*
* <p>In contrast to a plain bean factory, an ApplicationContext is supposed
* to detect special beans defined in its bean factory: Therefore, this class
* automatically registers BeanFactoryPostProcessors, BeanPostProcessors
* and ApplicationListeners that are defined as beans in the context.
*
* <p>A MessageSource may also be supplied as a bean in the context, with
* the name "messageSource"; else, message resolution is delegated to the
* parent context. Furthermore, a multicaster for application events can
* be supplied as "applicationEventMulticaster" bean in the context; else,
* a SimpleApplicationEventMulticaster is used.
*
* <p>Implements resource loading through extending DefaultResourceLoader.
* Therefore, treats plain resource paths as class path resources (only
* supporting full class path resource names that include the package path,
* e.g. "mypackage/myresource.dat").
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since January 21, 2001
* @see #refreshBeanFactory
* @see #getBeanFactory
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
* @see org.springframework.beans.factory.config.BeanPostProcessor
* @see ApplicationListener
* @see #MESSAGE_SOURCE_BEAN_NAME
* @see #APPLICATION_EVENT_MULTICASTER_BEAN_NAME
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* Name of the MessageSource bean in the factory.
* If none is supplied, message resolution is delegated to the parent.
* @see MessageSource
*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
/**
* Name of the ApplicationEventMulticaster bean in the factory.
* If none is supplied, a default SimpleApplicationEventMulticaster is used.
* @see org.springframework.context.event.ApplicationEventMulticaster
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
static {
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
ContextClosedEvent.class.getName();
}
//---------------------------------------------------------------------
// Instance data
//---------------------------------------------------------------------
/** Logger used by this class. Available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
/** Parent context */
private ApplicationContext parent;
/** BeanFactoryPostProcessors to apply on refresh */
private final List beanFactoryPostProcessors = new ArrayList();
/** Display name */
private String displayName = getClass().getName() + ";hashCode=" + hashCode();
/** System time in milliseconds when this context started */
private long startupTime;
/** ResourcePatternResolver used by this context */
private ResourcePatternResolver resourcePatternResolver;
/** MessageSource we delegate our implementation of this interface to */
private MessageSource messageSource;
/** Helper class used in event publishing */
private ApplicationEventMulticaster applicationEventMulticaster;
//---------------------------------------------------------------------
// Constructors
//---------------------------------------------------------------------
/**
* Create a new AbstractApplicationContext with no parent.
*/
public AbstractApplicationContext() {
this(null);
}
/**
* Create a new AbstractApplicationContext with the given parent context.
* @param parent the parent context
*/
public AbstractApplicationContext(ApplicationContext parent) {
this.parent = parent;
this.resourcePatternResolver = getResourcePatternResolver();
}
//---------------------------------------------------------------------
// Implementation of ApplicationContext
//---------------------------------------------------------------------
/**
* Return the parent context, or null if there is no parent
* (that is, this context is the root of the context hierarchy).
*/
public ApplicationContext getParent() {
return parent;
}
/**
* Set a friendly name for this context.
* Typically done during initialization of concrete context implementations.
*/
protected void setDisplayName(String displayName) {
this.displayName = displayName;
}
/**
* Return a friendly name for this context.
*/
public String getDisplayName() {
return displayName;
}
/**
* Return the timestamp (ms) when this context was first loaded.
*/
public long getStartupDate() {
return startupTime;
}
/**
* Publish the given event to all listeners.
* <p>Note: Listeners get initialized after the MessageSource, to be able
* to access it within listener implementations. Thus, MessageSource
* implementation cannot publish events.
* @param event event to publish (may be application-specific or a
* standard framework event)
*/
public void publishEvent(ApplicationEvent event) {
if (logger.isDebugEnabled()) {
logger.debug("Publishing event in context [" + getDisplayName() + "]: " + event.toString());
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
/**
* Return the internal MessageSource used by the context.
* @return the internal MessageSource (never null)
* @throws IllegalStateException if the context has not been initialized yet
*/
private ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
if (this.applicationEventMulticaster == null) {
throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
"call 'refresh' before multicasting events via the context: " + this);
}
return this.applicationEventMulticaster;
}
//---------------------------------------------------------------------
// Implementation of ConfigurableApplicationContext
//---------------------------------------------------------------------
public void setParent(ApplicationContext parent) {
this.parent = parent;
}
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor) {
this.beanFactoryPostProcessors.add(beanFactoryPostProcessor);
}
/**
* Return the list of BeanPostProcessors that will get applied
* to beans created with this factory.
*/
public List getBeanFactoryPostProcessors() {
return beanFactoryPostProcessors;
}
public void refresh() throws BeansException, IllegalStateException {
this.startupTime = System.currentTimeMillis();
// Tell subclass to refresh the internal bean factory.
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// Configure the bean factory with context-specific editors.
beanFactory.registerCustomEditor(Resource.class,
new ResourceEditor(this));
beanFactory.registerCustomEditor(URL.class,
new URLEditor(new ResourceEditor(this)));
beanFactory.registerCustomEditor(InputStream.class,
new InputStreamEditor(new ResourceEditor(this)));
beanFactory.registerCustomEditor(Resource[].class,
new ResourceArrayPropertyEditor(this.resourcePatternResolver));
// Configure the bean factory with context semantics.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyType(ResourceLoader.class);
beanFactory.ignoreDependencyType(ApplicationContext.class);
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered with the context instance.
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
if (logger.isInfoEnabled()) {
if (getBeanDefinitionCount() == 0) {
logger.info("No beans defined in application context [" + getDisplayName() + "]");
}
else {
logger.info(getBeanDefinitionCount() + " beans defined in application context [" + getDisplayName() + "]");
}
}
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors();
// Register bean processors that intercept bean creation.
registerBeanPostProcessors();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
refreshListeners();
// iIstantiate singletons this late to allow them to access the message source.
beanFactory.preInstantiateSingletons();
// Last step: publish corresponding event.
publishEvent(new ContextRefreshedEvent(this));
}
/**
* Return the ResourcePatternResolver to use for resolving location patterns
* into Resource instances. Default is PathMatchingResourcePatternResolver,
* supporting Ant-style location patterns.
* <p>Can be overridden in subclasses, for extended resolution strategies,
* for example in a web environment.
* <p><b>Do not call this when needing to resolve a location pattern.</b>
* Call the context's <code>getResources</code> method instead, which
* will delegate to the ResourcePatternResolver.
* @see #getResources
* @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
*/
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -