• Spring IOC - Spring启动过程解析


            Spring启动流程的核心逻辑主要体现在方法AbstractApplicationContext#refresh中,该方法没有被子类重写。

            本文主要从宏观层面对其进行剖析,从整体上感知。各执行步骤和作用按先后顺序如下表所示,其中标红方法为核心方法标绿色方法提供了扩展点。

    方法名

    主要作用

    prepareRefresh()

    记录容器启动时间、设置容器状态;提供扩展点用于自定义添加key-value属性

    obtainFreshBeanFactory()

    获取一个新鲜的beanFactory实例,该方法由两个子类实现:

    1.GenericApplicationContext:很简单,返回无参构造方法创建的beanFactory

    2.AbstractRefreshableApplicationContext:关闭当前beanFactory,创建新的beanFactory,体现了刷新的含义

    prepareBeanFactory(beanFactory)

    提前给beanFactory塞入bean实例:如BeanFactory,ResourceLoader等,以及设置类加载器、属性编辑器等

    postProcessBeanFactory(beanFactory)

    此处是Spring留的扩展点,目的是在beanFactory准备好后,留给用户最后对beanFactory做一些设置

    如对于Web应用,重写后给beanFactory塞入ServletContext等单例bean

    invokeBeanFactoryPostProcessors(beanFactory)

    调用BeanFactoryPostProcessor的实现类对BeanFactory进行后置处理,如调用ConfigurationClassPostProcessor对常用注解进行解析,生成BeanDefinition

    registerBeanPostProcessors(beanFactory)

    注册Bean的后置处理器,包括系统内置的和自定义的,如:AutowireAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor

    initMessageSource()

    初始化MessageSource,用于支持国际化

    initApplicationEventMulticaster()

    初始化事件派发器,用于支持事件监听

    onRefresh()

    Spring提供的扩展点,留给子类实现

    registerListeners()

    注册事件监听器

    finishBeanFactoryInitialization(beanFactory)

    实例化所有非懒加载的单例Bean,Spring Bean的生命周期就是从这里开始的

    finishRefresh()

    完成刷新,发布容器刷新完成事件等

            源码及注释如下:

    1. // Spring应用上下文的核心方法,它负责完成Spring容器的初始化和刷新工作
    2. @Override
    3. public void refresh() throws BeansException, IllegalStateException {
    4. synchronized (this.startupShutdownMonitor) {
    5. // Prepare this context for refreshing.
    6. // 准备刷新操作,包括记录容器启动时间、设置容器状态、获取属性、验证必要的属性
    7. prepareRefresh();
    8. // Tell the subclass to refresh the internal bean factory.
    9. // 获取一个新鲜的BeanFactory实例,该方法由子类实现
    10. // 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等,注意,此处是获取新的,销毁旧的,这就是刷新的意义
    11. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    12. // Prepare the bean factory for use in this context.
    13. // 对BeanFactory进行一些设置,例如设置类加载器、添加属性编辑器等
    14. prepareBeanFactory(beanFactory);
    15. try {
    16. // Allows post-processing of the bean factory in context subclasses.
    17. // 允许子类在BeanFactory标准初始化完成后对其进行进一步的处理
    18. // 此处是spring留的扩展点,目前是在beanFactory准备好后,留给用户最后对beanFactory做一些设置
    19. // 可参考GenericWebApplicationContext#postProcessBeanFactory实现
    20. postProcessBeanFactory(beanFactory);
    21. // Invoke factory processors registered as beans in the context.
    22. // 调用BeanFactoryPostProcessor的实现类对BeanFactory进行后置处理
    23. // 扫描解析的核心代码
    24. invokeBeanFactoryPostProcessors(beanFactory);
    25. // Register bean processors that intercept bean creation.
    26. // 注册BeanPostProcessor的实现类,用于在Bean创建过程中进行拦截
    27. registerBeanPostProcessors(beanFactory);
    28. // Initialize message source for this context.
    29. // 初始化MessageSource,用于支持国际化
    30. initMessageSource();
    31. // Initialize event multicaster for this context.
    32. // 初始化事件派发器,用于支持事件监听
    33. initApplicationEventMulticaster();
    34. // Initialize other special beans in specific context subclasses.
    35. // 留给子类实现,用于在容器刷新时进行特殊的处理
    36. onRefresh();
    37. // Check for listener beans and register them.
    38. // 注册事件监听器
    39. registerListeners();
    40. // Instantiate all remaining (non-lazy-init) singletons.
    41. // 实例化所有非懒加载的单例Bean
    42. // 这一步可谓和我们开发者打交道最多,我们自定义的Bean绝大多都是在这一步被初始化的,包括依赖注入等等
    43. // 因此了解这一步,能让我们更深入的了解Spring是怎么管理我们的Bean的生命周期,以及依赖关系的
    44. finishBeanFactoryInitialization(beanFactory);
    45. // Last step: publish corresponding event.
    46. // 完成刷新操作,包括发布容器刷新完成事件等
    47. finishRefresh();
    48. }
    49. catch (BeansException ex) {
    50. if (logger.isWarnEnabled()) {
    51. logger.warn("Exception encountered during context initialization - " +
    52. "cancelling refresh attempt: " + ex);
    53. }
    54. // Destroy already created singletons to avoid dangling resources.
    55. destroyBeans();
    56. // Reset 'active' flag.
    57. // 如果在刷新过程中出现异常,会执行该方法取消操作,并销毁已经创建的单例Bean,最后,会重置Spring核心中的一些缓存
    58. cancelRefresh(ex);
    59. // Propagate exception to caller.
    60. throw ex;
    61. }
    62. finally {
    63. // Reset common introspection caches in Spring's core, since we
    64. // might not ever need metadata for singleton beans anymore...
    65. resetCommonCaches();
    66. }
    67. }
    68. }

  • 相关阅读:
    ORI-GB-NP半乳糖介导冬凌草甲素/姜黄素牛血清白蛋白纳米粒的研究制备方法
    整数型常量池
    数据库注入提权总结(一)
    正式版 API 确定 | Android 12L Beta 1 发布
    前端常用的几种布局方式(易懂版)
    [vulnhub] Tr0ll: 2
    螺旋矩阵的实现
    学习笔记(9)JavaScript元素、节点
    c++ 深度拷贝和浅拷贝
    db-link 查询的语法约束
  • 原文地址:https://blog.csdn.net/zhangweiocp/article/details/134220616