ApplicationContext
在 Spring 中代表着一个高级的 IoC 容器,负责实例化、配置和组装对象。ApplicationContext
接口扩展自 BeanFactory
接口,添加了更多的企业级功能,比如更容易的国际化、事件传播、资源加载等。
ApplicationContext 接口关系
ApplicationContext
是一个功能丰富的接口,它继承自 ListableBeanFactory
和 HierarchicalBeanFactory
等多个接口,并且添加了其他特性。它的层级关系如下所示:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {// 各种方法
}
EnvironmentCapable
:提供对环境属性的访问。ListableBeanFactory
:允许列举所有 bean 实例,而不是按名字逐个查找。HierarchicalBeanFactory
:允许一个 bean 工厂成为另一个 bean 工厂的子工厂。MessageSource
:国际化功能。ApplicationEventPublisher
:事件发布功能。ResourcePatternResolver
:资源加载功能。
实现类 ClassPathXmlApplicationContext
一个非常常见的 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}}@Overrideprotected String[] getConfigLocations() {return this.configLocations;}// 其他方法...
}
ClassPathXmlApplicationContext
继承自 AbstractXmlApplicationContext
,在构造方法中可以指定配置文件的位置,还可以决定是否立即进行初始化(通过调用 refresh()
方法)。
refresh 方法解析
refresh()
方法在 AbstractApplicationContext
中定义,是 Spring 容器启动的核心方法。以下是简化版本的源代码:
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {@Overridepublic 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()
方法调用了一系列准备和初始化的步骤:
- prepareRefresh():准备上下文,设置开始时间、活动标志等。
- obtainFreshBeanFactory():刷新内部的 BeanFactory,并获取它。
- prepareBeanFactory(beanFactory):设置类加载器、后置处理器等。
- postProcessBeanFactory(beanFactory):提供子类覆写的扩展点,用于添加额外的处理。
- invokeBeanFactoryPostProcessors(beanFactory):调用所有注册的 BeanFactoryPostProcessor。
- registerBeanPostProcessors(beanFactory):注册 BeanPostProcessor。
- initMessageSource():初始化消息资源处理,用于国际化。
- initApplicationEventMulticaster():初始化事件广播器。
- onRefresh():由子类覆写,用于特定上下文的 bean 初始化。
- registerListeners():注册监听器。
- finishBeanFactoryInitialization(beanFactory):初始化剩余的单例 beans。
- finishRefresh():最后一步,广播相关事件(比如上下文刷新事件)。
总结
ApplicationContext
通过 refresh()
方法的调用来初始化 Spring 容器。这个方法是整个应用上下文生命周期中非常重要的一部分,它会创建和初始化所有的 beans,同时处理依赖注入。
正是通过这个复杂而强大的初始化过程,Spring 能够管理应用中的 beans,并提供如 AOP、事务管理、事件发布等特性。虽然 ApplicationContext
提供了非常丰富的功能,但是作为开发者,我们通常只需要与它的几个核心方法打交道,如 getBean()
、register()
、refresh()
等,而 Spring 框架会处理其背后的复杂逻辑。