【Spring总结】Refresh

Refresh

ApplicationContext refresh的流程概述

ApplicationContext是spring中的核心容器,refresh是ApplicationContext的一个方法,主要作用是用来初始化ApplicationContext。

refresh一共分为十二个步骤。所有的ApplicationContext有一个共同的父类叫AbstractApplicationContext。这个父类里有refresh方法,这个方法里面有12个比较重要的方法。

【Spring总结】Refresh_第1张图片

1、蓝色:代表做一些准备工作。

2—6、绿色:创建并准备BeanFactory对象。

为什么需要BeanFactory对象呢?

因为ApplicationContext只是一个外部容器,核心功能还需要交给BeanFactory来完成。(Bean的创建、Bean的依赖注入、Bean的初始化)

7—12、黄色:准备我们的ApplicationContext,为ApplicationContext里面一些特有的功能做一些准备。

11、红色:比较重要,是在创建和初始化我们的单例对象。容器当中的单例对象都是在第11步创建并初始化完成的。

1、prepareRefresh

要点
●这一步创建和准备 了Environment对象
●要理解 Environment对象的作用
●跟我学怎么调试代码

prepareRefresh主要就是准备了一个Environment对象,这个环境对象后续的代码里都会用到。

他就是为我们spring后续运行时提供一些键值信息。

systemProperties:java中的一些键值(java中的默认编码、文件分割符等)

systemEnvironment:提供了操作系统的键值对(java_home、path、classPath等)

自定义:从自定义的properties文件当中的读取到的信息。例如application.properties文件。

即Environment的作用就是管理各种键值信息,将来其他地方可以用到这些信息,例如@Value

总结

  • Environment 的作用之一是为后续@Value,值注入时提供键值

@Value怎么获取值并且解析值的过程

【Spring总结】Refresh_第2张图片

【Spring总结】Refresh_第3张图片

【Spring总结】Refresh_第4张图片

我们还需要做进一步解析,解析的时候需要用到Environment(它里面存的是这些键值)

Environment是一个接口,我们使用的时候创建它的实现类即可。

image-20220324173725887

【Spring总结】Refresh_第5张图片

利用Environment获取配置文件中的键值信息

image-20220324193136452

StandardEnvironment只能解析java和系统的键值,我们在配置文件中自定义的键值无法解析到。

【Spring总结】Refresh_第6张图片

解析SpEL表达式

【Spring总结】Refresh_第7张图片

2、obtainFreshBeanFactory

要点

  • 这一步获取(或创建) BeanFactory
  • 理解BeanFactory的作用
  • 理解BeanDefinition的作用
  • BeanDefinition从何而来
【Spring总结】Refresh_第8张图片

1、ApplicationContext和BeanFactory的关系?

第一步ApplicationContext里面有一个成员变量Environment创建好之后。第二步会获得第二个成员变量BeanFactory(ApplicationContext里面会有一个成员变量为BeanFactory)。ApplicationContext和BeanFactory是一个组合的关系。虽然在继承关系上BeanFactory是父接口,ApplicationContext是子接口,也就是说ApplicationContext扩展了一些BeanFactory的一些功能,但是在实际使用中他俩是组合关系。

ApplicationContext里面的一些功能并没有自己去实现,例如创建Bean,依赖注入、初始化,这些功能还是借助成员变量BeanFactory来完成的。

2、BeanFactory的成员变量进行初始化

BeanFactory要现有一些bean的定义,要先知道这个Bean长什么样子(Bean是单例还是多例,bean的初始化方法是什么,他有哪些属性需要依赖注入。这些信息都是使用BeanDefinition这个类去描述的,而benDefinitionMap就是用来存储所有的BeanDefinition)

总结

  • BeanFactory的作用是负责bean的创建、依赖注入和初始化
  • BeanDefinition作为bean的设计蓝图,规定了bean的特征,如单例多例、依赖关系、初始销毁方法等
  • BeanDefinition 的来源有多种多样,可以是通过xml获得、通过配置类获得、通过组件扫描获得,也可以是编程添加

【Spring总结】Refresh_第9张图片

【Spring总结】Refresh_第10张图片

通过配置类获取BeanDefinition

【Spring总结】Refresh_第11张图片

通过Bean工厂的后置处理器去解析定义的配置类。

因为spring的标准功能里是没办法识别加了注解@Bean的方法(spring不能把他识别为一个BeanDefinition),需要后置处理器去解析这些@Bean注解,包括Import,ImportResource注解等,那些注解都需要额外的代码去解析。

Bean工厂的后置处理器,对我们的Bean工厂去做一些功能的增强。可以识别一些注解,将这些注解标记的类也作为BeanDefinition添加到Bean工厂里面去。

image-20220324200528446

扫描指定包下标注了注解的类,将这些类添加到BeanFactory里

【Spring总结】Refresh_第12张图片

image-20220324200825584

总结:BeanFactory就是去创建Bean,但它不是一下子就能把Bean创建出来,需要借助BeanDefinition。ApplicationContext和BeanFactory是组合关系,ApplicationContext在Bean的管理上接住了BeanFactory的功能。

3、prepareBeanFactory

要点

  • 完善BeanFactory
  • 了解谁来解析SpEL
  • 了解谁来执行类型转换
  • 了解特殊bean的注入
  • 两个内置的BeanPostProcessor的作用

【Spring总结】Refresh_第13张图片

顾名思义就是在准备我们的Bean工厂,因为刚开始的Bean工厂里有很多成员变量没有被初始化。所谓的准备Bean工厂就是将这些成员变量初始化好,才能执行后续的工作。

beanExpressionResolver: 解析SpEL表达式,解析#{}的

propertyEditorRegistrars: 注册一些类型转换器(spring在进行值注入的时候,需要把字符串类型转换为其他类型)

resolvableDependencies: 去管理一些特殊的对象用来进行依赖注入。(大部分Bean都是被放在singletonObjects里去完成依赖注入,但是有些特殊的对象能不能注入,比如我想注入BeanFactory本身,我想注入ApplicationContext本身,这些对象不是一个真正的bean,没有在单例池里面,没有在BeanDefinition里面去定义。但是这些Bean也是可以注入的,那么查询这些特殊Bean的时候不是去singletonObjects,而是去resolvableDependencies里面去查询)

beanPostProcessors: 在Bean创建时,对Bean的功能进行一些扩展,对里面的注解进行一些识别。(spring的标准功能里功能是十分有限的,如果要对bean的创建做各种各样的扩展的话,需要借助beanPostProcessors来完成)。一些beanPostProcessors是在bean的创建过程中,对bean的创建、依赖注入各个阶段做一些功能增强。

【Spring总结】Refresh_第14张图片

4、postProcessBeanFactory

它是一个空实现,留给子类去实现。

ApplicationContext有一大类是web环境下的子类,有一大类是非web环境下的子类。web环境下的子类初始化BeanFactory就需要初始化更多的信息,比如要注册一些新的scope,非web环境下只需要singleton和proportype。但是web环境下还需要request、session这些

是一种模板方法的设计模式,refresh方法得主要脉络都被父类给规定死了,但是有一些可以扩展得方法把它留空,将来有子类去实现。

总结.

  • 一般 Web环境的ApplicationContext都要利用它注册新的Scope,完善Web下的BeanFactory
  • 体现的是模板方法设计模式

5、invokeBeanFactoryPostProcessors

要点

  • 理解beanFactory后处理器的作用
  • 掌握常见的beanFactory后处理器

通过后置处理器对bean工厂的另一种扩展方式,第四步把一些功能是留给子类去扩展。

【Spring总结】Refresh_第15张图片

总结

  • beanFactory后处理器,充当beanFactory的扩展点,可以用来补充或修改BeanDefinition
  • ConfigurationClassPostProcessor -解析@Configuration、@Bean、@lmport、 @PropertySource 等=
  • PropertySourcesPlaceHolderConfigurer -替换BeanDefinition中的${}

(正常的BeanFactory是没有解析这些注解的功能的,调用后置处理器ConfigurationClassPostProcessor可以解析他们,同时解析的目的就是为了多加一些BeanDefinition)

BeanFactory有两个扩展点,第一处就是交给子类去扩展,第二处就是交给bean的后置处理器

6、registerBeanPostProcessors

要点

  • 理解bean后处理器的作用
  • 掌握常见的bean后处理器

Bean工厂的后置处理器是对整个Bean工厂的功能进行增强的,但是registerBeanPostProcessors是bean的后置处理器就不一样了,它是对我们接下来bean的创建过程中做各种功能增强。

【Spring总结】Refresh_第16张图片

如果想要ApplicationContext完成各种各样更多的功能,一般就会在第六步加入更多的bean的后置处理器,这些Bean的后置处理器从哪来呢?都是从beanDefinitionMap去搜索,看看这些beanDefinitionMap中有没有人实现了BeanPostProcessors接口。如果实现了接口他就会识别出来,你是一个特殊的bean,是一个bean后置处理器,会把这样的bena创建出来,创建好之后把它添加到beanPostProcessors集合里面。将来在bean创建的时候就会用到这些后置处理器了。

【Spring总结】Refresh_第17张图片

常见的Bean后置处理器

【Spring总结】Refresh_第18张图片

总结

  • bean 后处理器,充当bean的扩展点,可以工作在bean的实例化、依赖注入、初始化阶段
  • AutowiredAnnotationBeanPostProcessor功能有:解析@Autowired, @Value 注解
  • CommonAnnotationBeanPqstProcessor 功能有:解析@Resource, @PostConstruct, @PreDestroy
  • AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标bean自动创建代理

注意:这一步只是找出来有哪些Bean的后置处理器,将他们加入到beanPostProcessors集合中,但是真正这些后置处理器发挥作用的是在bean的创建过程。(现在只是注册,并没有用到他们)

7、initMessageSource

要点

  • 理解MessageSource的作用
  • MessageSource 从何而来

【Spring总结】Refresh_第19张图片

前面的2-6都是在不断地完善BeanFactory,第七步是给ApplicationContext的成员变量进行初始化和赋值。第七步就是给Message进行初始化赋值的,他就是一个国际化功能。

总结

  • 实现国际化
  • 容器中一个名为messageSource的bean,如果没有,则提供空的MessageSource实现

8、initApplicationEventMulticaster

要点

  • 理解事件广播器的作用
  • 事件广播器从何而来.
  • 如何发布事件
【Spring总结】Refresh_第20张图片

广播器的作用:收发事件。发事件的就是Multicaster,在spring当中设置一些监听器来收事件。当事件发生了Multicaster发送给各个监听器对象。

来源:和MessageSource一样,它也是先去BeanFactory找,看看beanDefinitionMap里面有没有一个Multicaster,如果有,就把他作为applicationEventMulticaster的实现。如果没有,它会提供一个默认的实现。

Multicaster里面有一个集合,这个集合内部维护了所有的监听器,将来Multicatser发事件的时候就会遍历这个集合,将事件发送给对这个事件感兴趣的监听器。

总结

  • 用来发布事件给 监听器
  • 可以从容器中找名为applicationEventMulticaster的bean作为事件广播器,若没有,也会新建默认的事件广播器
  • 可以调用ApplicationContext.publishEvent(事件对象)来发布事件

9、onRefresh

要点

  • 这一步是空实现,留给子类扩展
  • 掌握对应的设计模式

总结

  • SpringBoot 中的子类可以在这里准备WebServer,即内嵌web容器
  • 体现的是模板方法设计模式

10、registerListeners

要点

  • 理解事件监听器作用
  • 监听器从何而来
  • 如何接收事件 .

【Spring总结】Refresh_第21张图片

作用:监听器来接收事件

来源:如果beanDefinitionMap里面的bean实现了ApplicationListerner的接口,在这一步就会把这些bean找出来,将他们加入到Multicaster的集合里。Multicaster发事件的时候就将其发送到监听器集合里。

总结

  • 用来接收事件
  • 部分监听器是事先编程添加的、另一部分监听器来自容器中的bean、还有-部分来自于@EventListener的解析
  • 实现ApplicationListener接口,重写其中onApplicationEvent(E e)方法即可

11、finishBeanFactorylnitialization

要点

  • 了解conversionService
  • 了解内嵌值解析器
  • 单例池- singletonObjects

【Spring总结】Refresh_第22张图片

conversionService:类型转换。

之前的propertyEditorRegistrars就是做类型转换的,为什么还需要conversionService?

因为之前的propertyEditorRegistrars接口功能上不完整,所以又设计了另一套接口。

embeddedValueResolvers:用来解析${}。它相当于又封装了一下,会间接调用Environment。

singletonObjects: 将在fininationMap中的非延迟的单例对象创建出来。(在创建的过程中,beanPostProcessors后置处理器都会派上用场。bean的创建、依赖注入、初始化)

总结

  • conversionService也是一 套转换机制,作为对PropertyEditor的补充
  • 内嵌值解析器用来解析@Value中的${},借用的是Environment的功能
  • 单例池用来缓存所有单例对象,对象的创建都分三个阶段(创建、依赖注入、初始化),每- -阶段都有不同的bean后处理器参与迸来,扩展功能

12、finishRefresh

要点

  • 了解lifecycleProcessor
  • 它从何而来
  • 如何控制lifecycle?
  • 发布ContextRefreshed事件

【Spring总结】Refresh_第23张图片

生命周期处理器(lifecycleProcessor):容器当中有很多的bean,他们都有自己独立的生命周期(服务启动,停止),他也是在容器当中去找看有没有对应周期处理器,如果有就用,没有就有一个默认的。

他里面有个start、stop方法,相当于大哥一样,它的start方法一旦执行,其他bean的start也要执行。它的stop一旦执行,其他bean的stop也要执行。

总结

  • 用来控制容器内需要生命周期管理的bean
  • 如果 容器中有名称为lifecycleProcessor的bean就用它,否则创建默认的生命周期管理器
  • 调用context的start,即可触发所有实现LifeCycle接口bean的start
  • 调用context的stop,即可触发所有实现LifeCycle接口bean的stop

发布事件标识refresh完成。

refresh12个步骤

【Spring总结】Refresh_第24张图片

  1. prepareRefresh-做好准备工作(创建Environment对象,为spring后续的运行提供一些键值信息)
  2. obtainFreshBeanFactory -创建或获取BeanFactory
  3. prepareBeanFactory -准备BeanFactory(为BeanFactory创建各个成员变量,EL表达式解析器、类型转换器、内置的BeanPostProcessor)
  4. postProcessBeanFactory- 子类扩展BeanFactory
  5. invokeBeanFactoryPostProcessors -后处理器扩展BeanFactory(Bean工厂的后置处理器:ConfigurationClassPostProceessors,解析配置类的注解:@Configuration、@Bean等)
  6. registerBeanPostProcessors -准备Bean后处理器(常见的有三个,一个是解析@Autwired注解,一个是解析@Resource、一个是解析@Aspect,创建代理类的)
  7. initMessageSource -为ApplicationContext提供国际化功能
  8. initApplicationEventMulticaster -为ApplicationContext提供事件发布器
  9. onRefresh- 留给子类扩展
  10. registerListeners -为ApplicationContext准备监听器
  11. finishBeanFactorylnitialization -初始化单例Bean,执行Bean后处理器扩展
  12. finishRefresh- 准备生命周期管理器,发布ContextRefreshed事件

2-6:都是在准备BeanFactory

一个是解析@Autwired注解,一个是解析@Resource、一个是解析@Aspect,创建代理类的)
7. initMessageSource -为ApplicationContext提供国际化功能
8. initApplicationEventMulticaster -为ApplicationContext提供事件发布器
9. onRefresh- 留给子类扩展
10. registerListeners -为ApplicationContext准备监听器
11. finishBeanFactorylnitialization -初始化单例Bean,执行Bean后处理器扩展
12. finishRefresh- 准备生命周期管理器,发布ContextRefreshed事件

2-6:都是在准备BeanFactory

从第7开始:回到ApplicationContext,为它的成员进行赋值

你可能感兴趣的:(Spring框架源码学习,java)