前言

前面的准备工作结束之后,就是进入核心代码 refresh。

源码

  1. public void refresh() throws BeansException, IllegalStateException {
  2. // 加锁
  3. synchronized (this.startupShutdownMonitor) {
  4. StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
  5. // 准备一些上下文
  6. prepareRefresh();
  7. // 获取准备后的 beanFactory DefaultListableBeanFactory
  8. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  9. // 准备 BeanFactory
  10. prepareBeanFactory(beanFactory);
  11. try {
  12. // 允许在上下文子类中对bean工厂进行后处理。
  13. postProcessBeanFactory(beanFactory);
  14. StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
  15. // 在上下文中调用注册为 beanFactory 后置处理器
  16. // 就是实现了 BeanFactoryPostProcessor 的 bean
  17. invokeBeanFactoryPostProcessors(beanFactory);
  18. // 注册后置处理的Bean到容器当中
  19. // 就是扩展了 BeanPostProcessor 的 Bean
  20. registerBeanPostProcessors(beanFactory);
  21. beanPostProcess.end();
  22. // 为此上下文初始化消息源。
  23. // 初始化国际化工具 MessageSource
  24. initMessageSource();
  25. // 为此上下文初始化事件广播器。
  26. initApplicationEventMulticaster();
  27. // 在特定上下文子类中初始化其他特殊bean。子类可以自己实现
  28. onRefresh();
  29. // 检查并注册监听器。
  30. registerListeners();
  31. // 实例化所有剩余的(非延迟初始化)单例。
  32. finishBeanFactoryInitialization(beanFactory);
  33. // 最后一步: 完成此上下文的刷新,调用 LifecycleProcessor 的 onRefresh()方法并发布
  34. finishRefresh();
  35. }
  36. catch (BeansException ex) {
  37. if (logger.isWarnEnabled()) {
  38. logger.warn("Exception encountered during context initialization - " +
  39. "cancelling refresh attempt: " + ex);
  40. }
  41. // 销毁已创建的单例以避免资源悬挂。
  42. destroyBeans();
  43. // 重置活动状态
  44. cancelRefresh(ex);
  45. // Propagate exception to caller.
  46. throw ex;
  47. }
  48. finally {
  49. // Reset common introspection caches in Spring's core, since we
  50. // might not ever need metadata for singleton beans anymore...
  51. resetCommonCaches();
  52. contextRefresh.end();
  53. }
  54. }
  55. }

源码就是密密麻麻的一大堆,源码上有相应的注释。
9-Spring refresh - 图1
下面就根据流程,一步一步的深入源码,了解到每一步都是做什么了。

容器刷新准备

prepareRefresh 这一步主要是准备一些上下文信息。就不过多介绍了。

obtainFreshBeanFactory

9-Spring refresh - 图2
下面关注初始化 BeanFactory 这一步:
进入源码:
9-Spring refresh - 图3
通过 Debug 可以看出 refreshBeanFactory() 这一步调用的是 org.springframework.context.support.GenericApplicationContext#refreshBeanFactory 中实现的方法。
继续跟进
9-Spring refresh - 图4
发现这块判断了一个 refreshed 刷新状态。
refreshBeanFactory 方法也有另一个实现是在 AbstractRefreshableApplicationContext 中, 只不过我的断点没有断进去,这块也一起看下。

  1. protected final void refreshBeanFactory() throws BeansException {
  2. // 如果存在 BeanFactory 则销毁 Bean 并关闭 BeanFactory
  3. if (hasBeanFactory()) {
  4. destroyBeans();
  5. closeBeanFactory();
  6. }
  7. try {
  8. // 创建一个默认的 BeanFactory
  9. DefaultListableBeanFactory beanFactory = createBeanFactory();
  10. beanFactory.setSerializationId(getId());
  11. // 设置属性
  12. customizeBeanFactory(beanFactory);
  13. // 加载 Bean 信息
  14. loadBeanDefinitions(beanFactory);
  15. this.beanFactory = beanFactory;
  16. }
  17. catch (IOException ex) {
  18. throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
  19. }
  20. }

其中会创建 BeanFactory 并加载 BeanDefinition。只不过我暂时没有断到,所以等后面遇到之后再详细介绍。

总结

9-Spring refresh - 图5
本文简单介绍了 refresh 的流程,并介绍了前两个部分:

  1. prepareRefresh 准备上下文信息
  2. obtainFreshBeanFactory 初始化 BeanFactory

    相关推荐