📄 abstractapplicationcontext.java
字号:
/**
* Return the list of BeanFactoryPostProcessors that will get applied
* to the internal BeanFactory.
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
*/
public List getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
this.startupTime = System.currentTimeMillis();
// Tell subclass to refresh the internal bean factory.
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// Populate the bean factory with context-specific resource editors.
ConfigurableBeanFactoryUtils.registerResourceEditors(beanFactory, this);
beanFactory.registerCustomEditor(Class.class, new ClassEditor(getClassLoader()));
// Configure the bean factory with context semantics.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.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.
registerListeners();
// Instantiate 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);
}
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* Must be called before singleton instantiation.
*/
private void invokeBeanFactoryPostProcessors() throws BeansException {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] factoryProcessorNames = getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessor that implement the Ordered
// interface and those that do not.
List orderedFactoryProcessors = new ArrayList();
List nonOrderedFactoryProcessorNames = new ArrayList();
for (int i = 0; i < factoryProcessorNames.length; i++) {
if (Ordered.class.isAssignableFrom(getType(factoryProcessorNames[i]))) {
orderedFactoryProcessors.add(getBean(factoryProcessorNames[i]));
}
else {
nonOrderedFactoryProcessorNames.add(factoryProcessorNames[i]);
}
}
// First, invoke the BeanFactoryPostProcessors that implement Ordered.
Collections.sort(orderedFactoryProcessors, new OrderComparator());
for (Iterator it = orderedFactoryProcessors.iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(getBeanFactory());
}
// Second, invoke all other BeanFactoryPostProcessors, one by one.
for (Iterator it = nonOrderedFactoryProcessorNames.iterator(); it.hasNext();) {
String factoryProcessorName = (String) it.next();
((BeanFactoryPostProcessor) getBean(factoryProcessorName)).postProcessBeanFactory(getBeanFactory());
}
}
/**
* Instantiate and invoke all registered BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
private void registerBeanPostProcessors() throws BeansException {
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
final int beanProcessorTargetCount = getBeanFactory().getBeanPostProcessorCount() + 1 +
getBeanNamesForType(BeanPostProcessor.class, true, false).length;
getBeanFactory().addBeanPostProcessor(new BeanPostProcessorChecker(beanProcessorTargetCount));
// Actually fetch and register the BeanPostProcessor beans.
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean post-processors apply to them!
Map beanProcessorMap = getBeansOfType(BeanPostProcessor.class, true, false);
List beanProcessors = new ArrayList(beanProcessorMap.values());
Collections.sort(beanProcessors, new OrderComparator());
for (Iterator it = beanProcessors.iterator(); it.hasNext();) {
getBeanFactory().addBeanPostProcessor((BeanPostProcessor) it.next());
}
}
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
*/
private void initMessageSource() throws BeansException {
if (containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = (MessageSource) getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
private void initApplicationEventMulticaster() throws BeansException {
if (containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)
getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster();
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
/**
* Template method which can be overridden to add context-specific refresh work.
* Called on initialization of special beans, before instantiation of singletons.
* @throws BeansException in case of errors during refresh
* @see #refresh
*/
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
private void registerListeners() throws BeansException {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
Collection listeners = getBeansOfType(ApplicationListener.class, true, false).values();
for (Iterator it = listeners.iterator(); it.hasNext();) {
addListener((ApplicationListener) it.next());
}
}
/**
* Subclasses can invoke this method to register a listener.
* Any beans in the context that are listeners are automatically added.
* @param listener the listener to register
*/
protected void addListener(ApplicationListener listener) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
/**
* Publishes a ContextClosedEvent and destroys the singletons
* in the bean factory of this application context.
* @see org.springframework.context.event.ContextClosedEvent
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -