网络异常,图片无法展示
|
前言
前面的准备工作结束之后,就是进入核心代码 refresh。
源码
public void refresh() throws BeansException, IllegalStateException { // 加锁 synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); // 准备一些上下文 prepareRefresh(); // 获取准备后的 beanFactory DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 准备 BeanFactory prepareBeanFactory(beanFactory); try { // 允许在上下文子类中对bean工厂进行后处理。 postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); // 在上下文中调用注册为 beanFactory 后置处理器 // 就是实现了 BeanFactoryPostProcessor 的 bean invokeBeanFactoryPostProcessors(beanFactory); // 注册后置处理的Bean到容器当中 // 就是扩展了 BeanPostProcessor 的 Bean registerBeanPostProcessors(beanFactory); beanPostProcess.end(); // 为此上下文初始化消息源。 // 初始化国际化工具 MessageSource initMessageSource(); // 为此上下文初始化事件广播器。 initApplicationEventMulticaster(); // 在特定上下文子类中初始化其他特殊bean。子类可以自己实现 onRefresh(); // 检查并注册监听器。 registerListeners(); // 实例化所有剩余的(非延迟初始化)单例。 finishBeanFactoryInitialization(beanFactory); // 最后一步: 完成此上下文的刷新,调用 LifecycleProcessor 的 onRefresh()方法并发布 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 销毁已创建的单例以避免资源悬挂。 destroyBeans(); // 重置活动状态 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(); contextRefresh.end(); } } }
源码就是密密麻麻的一大堆,源码上有相应的注释。
网络异常,图片无法展示
|
下面就根据流程,一步一步的深入源码,了解到每一步都是做什么了。
容器刷新准备
prepareRefresh
这一步主要是准备一些上下文信息。就不过多介绍了。
obtainFreshBeanFactory
网络异常,图片无法展示
|
下面关注初始化 BeanFactory 这一步:
进入源码:
网络异常,图片无法展示
|
通过 Debug 可以看出 refreshBeanFactory()
这一步调用的是 org.springframework.context.support.GenericApplicationContext#refreshBeanFactory
中实现的方法。
继续跟进
网络异常,图片无法展示
|
发现这块判断了一个 refreshed
刷新状态。
refreshBeanFactory
方法也有另一个实现是在 AbstractRefreshableApplicationContext
中, 只不过我的断点没有断进去,这块也一起看下。
protected final void refreshBeanFactory() throws BeansException { // 如果存在 BeanFactory 则销毁 Bean 并关闭 BeanFactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 创建一个默认的 BeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // 设置属性 customizeBeanFactory(beanFactory); // 加载 Bean 信息 loadBeanDefinitions(beanFactory); this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
其中会创建 BeanFactory 并加载 BeanDefinition。只不过我暂时没有断到,所以等后面遇到之后再详细介绍。
总结
网络异常,图片无法展示
|
本文简单介绍了 refresh 的流程,并介绍了前两个部分:
- prepareRefresh 准备上下文信息
- obtainFreshBeanFactory 初始化 BeanFactory