📄 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.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
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.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;
/**
* Partial implementation of ApplicationContext. Doesn't mandate the type
* of storage used for configuration, but implements common 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 be also supplied as a bean in the context, with
* the name "messageSource". Else, message resolution is delegated to the
* parent context.
*
* <p>Implements resource loading through extending DefaultResourceLoader.
* Therefore, treats resource paths as class path resources. Only supports
* full classpath resource names that include the package path, like
* "mypackage/myresource.dat".
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since January 21, 2001
* @see #refreshBeanFactory
* @see #getBeanFactory
* @see #MESSAGE_SOURCE_BEAN_NAME
*/
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;
/** 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() {
}
/**
* Create a new AbstractApplicationContext with the given parent context.
* @param parent the parent context
*/
public AbstractApplicationContext(ApplicationContext parent) {
this.parent = parent;
}
//---------------------------------------------------------------------
// 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());
}
this.applicationEventMulticaster.multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
//---------------------------------------------------------------------
// 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;
}
/**
* Load or reload configuration.
* @throws org.springframework.context.ApplicationContextException if the
* configuration was invalid or couldn't be found, or if configuration
* has already been loaded and reloading is forbidden
* @throws BeansException if the bean factory could not be initialized
*/
public void refresh() throws BeansException {
this.startupTime = System.currentTimeMillis();
// tell subclass to refresh the internal bean factory
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// configure the bean factory with context semantics
beanFactory.registerCustomEditor(Resource.class, new ResourceEditor(this));
beanFactory.registerCustomEditor(InputStream.class, new InputStreamEditor(new ResourceEditor(this)));
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 (getBeanDefinitionCount() == 0) {
logger.warn("No beans defined in ApplicationContext [" + getDisplayName() + "]");
}
else {
logger.info(getBeanDefinitionCount() + " beans defined in ApplicationContext [" + getDisplayName() + "]");
}
// invoke factory processors registered as beans in the context
invokeBeanFactoryPostProcessors();
// register bean processor 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -