概要
过度
我们前面介绍了使用ApplicationContext
的原因,并提出了一个新的实例。我们现在从那个实例入手,对ApplicationContext
的整体实现逻辑做一个梳理介绍。
内容简介
梳理ApplicationContext
整体思路。
所属环节
ApplicationContext
整体思路梳理
上下环节
上文: ApplicationContext
引入
下文: ApplicaitonContext
中的各个环节,进入进行详细介绍
源码解析
入口
public class MyApplicationContextTest {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("");
context.getBean("");
}
}
我们从这个例子开始入手。根据我们最开始的引入介绍很容易想到,ApplicationContext
中大部分的附加是对BeanFactory
中提供的各种配置,针对用户的使用场景进行了配置。
所以我们重点关注的其实是ApplicationContext context = new ClassPathXmlApplicationContext("");
这一行。我们接下来进去看一下
外层逻辑介绍
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();
}
}
我们很容易发现:其实包含了两步,一是存储了配置文件的信息,二是调用了一个刷新函数,在这个函数中肯定存在了对BeanFactory
的功能补充和ApplicationContext
的初始化配置。
refresh()
// TODO 模版方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备此 ApplicationContext
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// BeanFactory 的初始化及对应的 BD 的加载
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 对 BeanFactory 中的一些和上下文相关的属性进行设置和同步。
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 定义了一个钩子,供子类实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用 BeanFactory 的后处理器对其进行处理
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册那些拦截 Bean 创建的后处理器
// 注意,上面 invokeBeanFactoryPostProcessors() 各种实例化各种注册,操作的都是针对 factory 的后处理器。这里才是针对 bean
// 的后处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化本 context 的 Message 源【国际化和本土化】【将对应的信息符号转化成对应的语言提示】
// TODO 没啥需要,最后再看
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件广播相关的东西
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 子实现类根据各自情况实现其他的特殊 Bean 的处理
// 算是留下的一个钩子
onRefresh();
// Check for listener beans and register them.
// 找出所有可注册的监听器并注册成有效的监听器,完成初始化后将之前缓存的事件散发出去
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 将剩余的非懒加载的单例加载一下
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 完成启动,散发相应事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
思路比较明晰,一条线走下来:

后面我们会专门针对所有的步骤进行一一解读。
网友评论