ApplicationContext
在 Spring 中代表着一个高级的 IoC 容器,负责实例化、配置和组装对象。ApplicationContext
接口扩展自 BeanFactory
接口,添加了更多的企业级功能,比如更容易的国际化、事件传播、资源加载等。
ApplicationContext
是一个功能丰富的接口,它继承自 ListableBeanFactory
和 HierarchicalBeanFactory
等多个接口,并且添加了其他特性。它的层级关系如下所示:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
// 各种方法
}
EnvironmentCapable
:提供对环境属性的访问。ListableBeanFactory
:允许列举所有 bean 实例,而不是按名字逐个查找。HierarchicalBeanFactory
:允许一个 bean 工厂成为另一个 bean 工厂的子工厂。MessageSource
:国际化功能。ApplicationEventPublisher
:事件发布功能。ResourcePatternResolver
:资源加载功能。一个非常常见的 ApplicationContext
实现是 ClassPathXmlApplicationContext
,它从类路径下的 XML 文件加载配置元数据并初始化应用上下文。我们分析一下它的关键源代码。
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private String[] configLocations;
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh(); // 初始化 ApplicationContext
}
}
@Override
protected String[] getConfigLocations() {
return this.configLocations;
}
// 其他方法...
}
ClassPathXmlApplicationContext
继承自 AbstractXmlApplicationContext
,在构造方法中可以指定配置文件的位置,还可以决定是否立即进行初始化(通过调用 refresh()
方法)。
refresh()
方法在 AbstractApplicationContext
中定义,是 Spring 容器启动的核心方法。以下是简化版本的源代码:
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 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 all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
// 其他异常处理代码...
}
}
// 其他方法...
}
refresh()
方法调用了一系列准备和初始化的步骤:
ApplicationContext
通过 refresh()
方法的调用来初始化 Spring 容器。这个方法是整个应用上下文生命周期中非常重要的一部分,它会创建和初始化所有的 beans,同时处理依赖注入。
正是通过这个复杂而强大的初始化过程,Spring 能够管理应用中的 beans,并提供如 AOP、事务管理、事件发布等特性。虽然 ApplicationContext
提供了非常丰富的功能,但是作为开发者,我们通常只需要与它的几个核心方法打交道,如 getBean()
、register()
、refresh()
等,而 Spring 框架会处理其背后的复杂逻辑。