Spring中Bean生命周期与Spring的执行流程

Spring中Bean的生命周期

  1. 实例化bean对象,并设置属性
  2. 检查Aware接口,并设置依赖
  3. 调用 BeanPostProcess的前置初始化方法postProcessBeforeInitialization()
  4. 调用InitializingBean的afterPropertiesSet()方法
  5. 调用自身init-method方法
  6. 调用 BeanPostProcess的后置初始化方法postProcessAfterInitialization()
  7. 完成创建- 使用
  8. 销毁
    1. 检查DisposableBean接口,若实现了则调用destroy销毁方法
    2. 若配置了destry-method属性,就调用这个配置的销毁方法

在这里插入图片描述

总的来说就是 实例化 — 属性赋值 — 初始化 — 销毁


  • 单例模式下,容器启动时创建并初始化bean,容器关闭时销毁bean
  • 多实例模式,容器启动时创建不创建bean,仅在bean被调用时创建和初始化bean,且不管理bean的销毁,即容器关闭时不会销毁bean。

Spring的执行(启动)流程

入口:AnnotationConfigApplicationContext

在这里插入图片描述

先了解几个概念

  1. DefaultListableBeanFactory: beanFactory 工厂
    这个类有几个非常重要的属性:beanDefinitionMap是一个map,用来存放bean所对应的BeanDefinition;beanDefinitionNames是一个List集合,用来存放所有bean的name;singletonObjects是一个Map,用来存放所有创建好的单例Bean。
  2. BeanDefinition对象: 它存储了 bean 对象的所有特征信息,如是否单例,是否懒加载,factoryBeanName 等
  3. AnnotatedBeanDefinitionReader: 注解读取器
  4. ClassPathBeanDefinitionScanner: 路径扫描器
  5. refresh: 刷新容器(重点
  6. Spring中有很多后置处理器,但最终可以分为两种,一种是BeanFactoryPostProcessor,一种是BeanPostProcessor。前者的用途是用来干预BeanFactory的创建过程,后者是用来干预Bean的创建过程。后置处理器的作用十分重要,bean的创建以及AOP的实现全部依赖后置处理器。

执行流程

  • 入口:AnnotationConfigApplicationContext的构造方法
    在这里插入图片描述
    1.1 构造函数中先调用了this(),调用了无参在这里插入图片描述

    • 因为java继承,这里会先调用父类的无参构造方法
      在父类的构造器中实例化了beanFactory,即直接new了一个DefaultListableBeanFactory。
      在这里插入图片描述

    • this()中通过new AnnotatedBeanDefinitionReader(this)实例化了一个Bean读取器,并向BeanDefinitionMap中添加了7个元素。通过new ClassPathBeanDefinitionScanner(this)实例化了一个扫描器(该扫描器在后面并没有用到)。

      this.reader = new AnnotatedBeanDefinitionReader(this);最后会调用到registerAnnotationConfigProcessors(BeanDefinitionRegistry registry,Object source)方法,这个方法会向BeanDefinitionMap中添加了7个类:
      ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory

    1.2 register(componentClasses)
    传入的配置类componentClasses解析成BeanDefinition(实际类型为AnnotatedGenericBeanDefinition),然后放入到BeanDefinitionMap中,这样后面在ConfigurationClassPostProcessor中能解析componentClasses

    1.3 refresh()
    refresh()方法是整个Spring容器的核心,在这个方法中进行了bean的实例化、初始化、自动装配、AOP等功能。
    在refresh()方法中,比较重要的方法为invokeBeanFactoryPostProcessors(beanFactory) 和 finishBeanFactoryInitialization(beanFactory)。
    在这里插入图片描述

    1. postProcessBeanFactory(beanFactory)
      空方法,由子类实现
    2. invokeBeanFactoryPostProcessors(beanFactory)
      该方法的作用是执行所有的BeanFactoryPostProcessor
      由于Spring会内置一个BeanFactoryPostProcessor,即ConfigurationClassPostProcessor(如果开发人员不自定义,默认情况下只有这一个BeanFactoryPostProcessor),这个后置处理器在处理时,会解析出所有交由Spring容器管理的Bean,将它们解析成BeanDefinition,然后放入到BeanFactory的BeanDefinitionMap中。
    3. registerBeanPostProcessors(beanFactory)
      该方法的作用是找到所有的BeanPostProcessor,然后将这些BeanPostProcessor实例化 (会调用getBean()方法,getBean()方法的主要逻辑是:如果bean存在于BeanFactory中,则返回bean;如果不存在,则会去创建 ) 。将这些PostProcessor实例化后,最后放入到BeanFactory的beanPostProcessors属性中。
      最后再重新注册了ApplicationListenerDetector,这样做的目的是为了将ApplicationListenerDetector放入到后置处理器的最末端。
      registerBeanPostProcessor() 最终调用的是PostProcessorRegistrationDelegate.registerBeanPostProcessors()
      从上面的源码中可以发现,BeanPostProcessor存在优先级,实现了PriorityOrdered接口的优先级最高,其次是Ordered接口,最后是普通的BeanPostProcessor。优先级最高的,会最先放入到beanPostProcessors这个集合的最前面,这样在执行时,会最先执行优先级最高的后置处理器(因为List集合是有序的)。
      这样在实际应用中,如果我们碰到需要优先让某个BeanPostProcessor执行,则可以让其实现PriorityOrdered接口或者Ordered接口。

    插个问题:如何找到所有的BeanPostProcessor? 包括Spring内置的和开发人员自定义的。
    :由于在refresh()方法中,会先执行完invokeBeanFactoryPostProcessor()方法,这样所有自定义的BeanPostProcessor类均已经被扫描出并解析成BeanDefinition(扫描和解析又是谁做的呢?ConfigurationClassPostProcessor做的),存入至BeanFactory的BeanDefinitionMap,所以这儿能通过方法如下一行代码找出所有的BeanPostProcessor,然后通过getBean()全部实例化,最后再将实例化后的对象加入到BeanFactory的beanPostProcessors属性中,该属性是一个List集合。
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    1. initMessageSource()
      用来支持消息国际化,现在一般项目中不会用到国际化相关的知识。
    2. initApplicationEventMulticaster()
      该方法初始化了一个事件广播器,如果容器中存在了beanName为applicationEventMulticaster的广播器,则使用该广播器;如果没有,则初始化一个SimpleApplicationEventMulticaster。
      该事件广播器是用来做应用事件分发的,这个类会持有所有的事件监听器(ApplicationListener),当有ApplicationEvent事件发布时,该事件监听器能根据事件类型,检索到对该事件感兴趣的ApplicationListener。
    3. onRefresh()
      执行其他的初始化操作,例如和SpringMVC整合时,需要初始化一些其他的bean,但是对于纯Spring工程来说,onRefresh()方法是一个空方法。
    4. registerListeners()
      这一步会将自定义的listener的bean名称放入到事件广播器中,同时还会将早期的ApplicationEvent发布(对于单独的Spring工程来说,在此时不会有任何ApplicationEvent发布,但是和SpringMVC整合时,SpringMVC会执行onRefresh()方法,在这里会发布事件)。
    5. finishBeanFactoryInitialization(beanFactory)
      该方法十分重要,它完成了所有非懒加载的单例Bean的实例化和初始化,属性的填充以及解决了循环依赖等问题。
      主要流程为getBean() ——>doGetBean()——>createBean()——>doCreateBean()
      在bean的创建过程中,一共出现了8次BeanPostProcessor的执行,在这些后置处理器的执行过程中,完成了AOP的实现、bean的自动装配、属性赋值等操作。
    6. finishRefresh()
      执行到这一步,Spring容器的启动基本结束了,此时Bean已经被实例化完成,且完成了自动装配。执行finishRefresh()方法,是为了在容器refresh()结束时,做一些其他的操作,例如:发布ContextRefreshedEvent事件,这样当我们想在容器refresh完成后执行一些特殊的逻辑,就可以通过监听ContextRefreshedEvent事件来实现。
      Spring内置了四个和应用上下文(ApplicationContextEvent)有关的事件:ContextRefreshedEvent、ContextStartedEvent、ContextStopedEvent、ContextClosedEvent。
    7. resetCommonCaches()
      最后在refresh()方法的finally语句块中,执行了resetCommonCaches()方法。因为在前面创建bean时,对单例bean的元数据信息进行了缓存,而单例bean在容器启动后,不会再进行创建了,因此这些缓存的信息已经没有任何用处了,在这里进行清空,释放部分内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值