Refresh解析

目录

后置处理器PostProcessor

PostProcessor的种类

Aware

事件监听模式

Spring容器的刷新逻辑

ApplicationContext refresh的流程概述

1---prepareRefresh

2---obtainFreshBeanFactory

3---prepareBeanFactory

4---postProcessBeanFactory

5---invokeBeanFactoryPostProcessors

6---registerBeanPostProcessors

7---initMessageSource

8---initApplicationEventMulticaster

9---onRefresh

10---registerListeners

11---finishBeanFactoryInitialization

12---finishRefresh

小结


  • 后置处理器PostProcessor

  • 本身也是一种需要注册到容器里的Bean
    • 其里面的方法会在特定的时机被容器调用
    • 实现不改变容器或者Bean核心逻辑的情况下对Bean进行扩展
    • 对Bean进行包装,影响其行为、修改Bean的内容等
  • PostProcessor的种类

  • 大类分为容器级别的后置处理器以及Bean级别的后置处理器
    • BeanDefinitionRegistryPostProcessor
    • BeanFactoryPostProcessor
    • BeanPostProcessor
  • 前两个是容器级别的处理器,最后一个是Bean级别的处理器
  • BeanDefinitionRegistryPostProcessor
    • 负责自定义的BeanDefinition的注册;允许在正常的BeanFactoryPostProcessor检测开始之前注册更多的自定义beanDefinition

  • 继承BeanFactoryPostProcessor,可以看成是一种特殊的BeanFactoryPostProcessor;他只有一个方法
  • 方法展示:
  • 创建BeanDefinition实例,再将其注册到形参register里面
  • 编写实现类;要先将其实现类注入到容器里,才能和容器对话

  • main函数中获得我们刚注册的bean实例

  • BeanFactoryPostProcessor:影响容器的行为
  • BeanPostProcessor:
  • 对于每个由容器创建的bean实例,BeanPostProcessor都会在调用容器初始化之前以及在任何bean初始化回调之后,都从容器获得回调执行;注意不是BeanDefinition实例
  • 方法展示:

  • 在main函数执行发现每一个Spring管理的bean都会去执行那两个方法,且先执行before再after

  • 可以使用BeanPostProcessor的能力对bean进行包装即在bean创建之后在postProcessAfterInitialization对bean包装统一的逻辑,比如耗时统计的日志记录,之后再返回增强的bean
  • 在源码中在逐个执行排序好的postprocessors时,采用责任链模式来执行,每个接收者都包含对另外一个接收者的引用;如果一个对象不能处理该请求,会把该对象转发给下一个接收者,以此类推
  • Aware

  • 容器对bean本身的逻辑是无侵入的,因此bean不需要了解容器的状态可直接使用容器
  • 但在某些情况下需要在bean中对容器进行直接操作的,这时就需要在bean中设置对容器的感知了,这便是Aware接口的作用
  • 这个接口里面什么方法都没有,所以只能当作标签来使用
  • ApplicationContextAware

  • 在容器创建这个bean实例的时候,将容器本身的实例作为参数传进来给这个bean来使用
  • BeanFactoryAware:获取当前的BeanFactory,这样就可以调用容器的服务
  • ApplicationEventPublisherAware:获取发布器实例已发布的事件
  • 想实现什么功能就调用相关接口
  • 例:获取注册到这个容器里的所有beandefinition的name

  • main函数

  • 注意:想要获取容器提供的资源,除了继承Aware接口之外,类本身还是要被Spring容器管理的bean才行
  • 事件监听模式

  • 回调函数
  • 往组件注册自定义的方法以便组件在特定场景下调用
  • Thread类就是组件,run()方法就是回调函数,我们并不希望直接调用Runnable里面的run方法
  • 而是希望Thread组件在某个时刻去执行它,该时刻就是在调用start方法之后再去执行
  • 事件监听器模式

  • 监听器将监听感兴趣的事件,一旦事件发生,便做出响应
  • 事件源( Event Source ):比如说一个按钮,要想使某个按钮对某个事件做出响应,就需要监听器
  • 事件监听器( Event Listener ):需要注册到事件源上才能被调用,主要用来监听事件并进行事件处理或者转发
  • 事件对象( Event Object ):负责事件源和事件监听器之间的信息传递
  • 例子:
  • 1---创建事件

  • 2---创建事件监听器

  • 实现类

  • 3---创建事件源
  • 因为需要将事件监听器注册到事件源里,事件监听器有多个,所以需要定义一个List集合
  • 提供一个共有的方法供外界输入数据,还有输出数据即发布事件的方法
  • 主要发布给listener,遍历所有的listener,都发一个事件,listener再去处理事件

  • 还需要将lisener注册到事件源里面,注册好之后,事件源去发布事件,交给事件监听器去处理

  • 使用事件监听器模式可以解耦,事件监听器和事件源是可以分开开发的
  • 其中只有事件作为联系,不用关心另一方怎么实现的,事件监听器其实是观察者模式的一种实现
  • 事件源组件和事件等于观察者的主题主键类似,事件监听器对标观察者模式的观察者
  • Spring的事件驱动模型

  • 事件驱动模型的三大组成部分
    • (一)事件:ApplicatinEvent抽象类

    • 继承自jdk的EventObject,所有事件将继承于ApplicatinEvent,并通过里面的source成员变量获得事件
    • 事件源就是发布事件的地方,这里指的就是容器本身
    • ApplicationEvent并不单单指的是容器事件,为了专门给容器定制事件,产生了ApplicationContextEvent子类,用来表示容器事件
    • 下面是框架对其的实现类
    • 在容器中发布一个任意类型的事件之后,会被自动封装为PayloadApplicationEvent类

    • (二)事件监听器 : ApplicationListener

    • 用户可以实现此接口,实现里面的方法实现自定义监听器;也可以使用注解的方式对类进行监听
    • 这样就可以将该类晋升为监听器,同时使用sayHello方法进行监听

    • SmartApplicationListener
    • 继承order,可以给事件排序

    • 判断事件类型和事件源类型是否和当前监听者匹配,这样监听者就可以筛选自己感兴趣的事件或者事件源

    • GenericApplicationListener

    • ResolvableType:获取泛型信息的工具,可以通过它获得泛型的任何信息类似于反射

    • (三)事件发布器 : Publisher以及Multicaster
    • 可以在bean里面通过Aware获得ApplicationEvnetPublisher实例,其实也就是获得容器这个实例
    • 就可以发布自定义的事件给容器里注册的自定义的eventListener去处理

    • 发现容器ApplicationContext继承ApplicationEventPublisher

    • ApplicationEventPublisher

    • 它里面的两个方法都是用来发布事件的,即这个接口只能用来发布事件
    • ApplicationEventMulticaster
    • 有添加和删除listener、发布的功能

    • Executor:执行器,说明它支持多线程去处理监听器的方法
    • 为什么需要ApplicationEventPublisher和ApplicationEventMulticaster这两个接口?
    • 既然ApplicationEventMulticaster已经具有了所有的功能,为什么不直接使用它替代掉ApplicationEventPublisher?
    • 比如说像bean容器本身(applicationcontext)就只想发布事件,而不想维护事件监听器这些
    • 所以Spring将事件源做了进一步分割,抽象出事件发布器接口,将ApplicationEventMulticaster作为代理
    • 就像applicationcontext用我们的DefaultListableFactory作为代理一样,让ApplicationEventPublisher的实现类来实现publishEvent里面的逻辑
    • 那ApplicationEventPublisher里面就主要实现调用ApplicationEventMulticaster实现类的multicastEvent来发布事件就可以了
  • Spring容器的刷新逻辑

  • 刷新的意思就是将BeanFactory清空为初始状态,然后再按照程序意图填满各种bean实例
  • 注解的beanDefinition注册时,DefaultListableBeanFactory这个实例已经在注册主键类之前,也就是调用容器的构造函数时就已经创建了
  • 后置器ApplicationContextAwareProcessor:当bean实例继承ApplicationContextAware接口时,去给这些bean实例注入ApplicationContext对象
  • 调用完了容器级别的后置处理器之后,接下来就是bean级别的后置处理器
  • register这一步就是将先前定义的bean级别的后置处理器给注册到容器里,方便后续在调用getBean方法去创建bean实例时,在特定的环节去触发这些后置处理器执行一些特定的逻辑,比如AOP织入
  • 初始化事件发布器:用来接收实现ApplicationEventPublisher接口类发送过来的不同的事件,并派给不同的事件监听者进行处理
  • onRefresh():钩子方法,用于初始化其他特殊的bean,发生在单例的bean初始化之前去执行
  • 往先前已经初始化出来的ApplicationEventMulticaster去注册相关的监听器,用来监听不同的事件

  • ApplicationContext refresh的流程概述

  • ApplicationContext是Spring中的核心容器,refresh是ApplicationContext的一个方法,主要作用是用来初始化ApplicationContext
  • refresh一共分为十二个步骤
  • 所有的ApplicationContext有一个共同的父类叫AbstractApplicationContext
  • 这个父类里有refresh方法,这个方法里面有12个比较重要的方法

  • (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
  • 2---obtainFreshBeanFactory

  • 作用:初始化beanFactory,加载并解析配置

  • 方法中做了二件事:
    • refreshBeanFactory():创建beanFactory、指定序列化Id、定制beanFactory、加载bean定义
    • getBeanFactory():返回beanFactory实例
  • refreshBeanFactory()方法主要执行:
    • 如果有bean工厂,销毁bean以及关闭bean工厂
    • createBeanFactory():创建beanFactory
    • beanFactory.setSerializationId(getId()):指定序列化Id
    • customizeBeanFactory():定制BeanFactory
    • loadBeanDefinitions():加载bean定义
  • 3---prepareBeanFactory

  • 作用:配置工厂的标准上下文特征,为beanFactory设置类加载器、后置处理器等
  • 方法逻辑梳理如下:
    • 设置类加载器,默认是RestartClassLoader;
    • 设置表达式解析器StandardBeanExpressionResolver,比如SPEL语法就是该解析器内维护的SpelExpressionParser进行处理的;
    • 向Set<PropertyEditorRegistrar> propertyEditorRegistrars 添加 ResourceEditorRegistrar;
    • 注册beanPostProcessor如ApplicationContextAwareProcessor;
    • 向Set<Class<?>> ignoredDependencyInterfaces中添加对象如EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware;也就是说这些类将不会通过Autowired自动注入而是会被BeanFactory通过比BeanFactoryAware或者ApplicationContext通过ApplicationContextAware这种方式设置
    • 向Map<Class<?>, Object> resolvableDependencies放入BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext;表示是已经解析的依赖可以直接使用
    • 注册应用监听器检测器,如果实例化bean是ApplicationListener,则其将会被放入applicationListeners;
    • 如果 loadTimeWeaver 存在于beanFactory,则注册LoadTimeWeaverAwareProcessor并设置TempClassLoader为ContextTypeMatchClassLoader
    • 注册默认的环境信息bean如environment、systemProperties、systemEnvironment
  • 4---postProcessBeanFactory

  • Spring中并没有具体去实现postProcessBeanFactory方法,是提供给想要实现BeanPostProcessor的三方框架使用的
  • 谁要使用谁就去实现
  • 作用是在BeanFactory准备工作完成后做一些定制化的处理,一般结合BeanPostProcessor接口的实现类一起使用,注入一些重要资源(类似Application的属性和ServletContext的属性)
  • 最后需要设置忽略这类BeanPostProcessor子接口的自动装配
  • 是一种模板方法的设计模式,refresh方法的主要脉络都被父类给规定死了,但是有一些可以扩展的方法把它留空,将来有子类去实现
  • 5---invokeBeanFactoryPostProcessors

  • 主要用来调用beanFactory后置处理器来修改beanDefinition
  • 该方法实例化并调用已经注册到beanFactory的beanFactoryPostProcessor实例
  • BeanFactory有两个扩展点,第一处就是交给子类去扩展,第二处就是交给bean的后置处理器
  • 6---registerBeanPostProcessors

  • 本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中
  • BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理
  • 在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候
  • 具体的:在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法
  • 7---initMessageSource

  • 主要用于国际化,说简单点就是不同语言之间的翻译
  • 该方法将会初始化MessageSource并尝试设置parentMessageSource,然后作为单例bean注册到容器中
  • 通常注册是 DelegatingMessageSource 实例
  • 8---initApplicationEventMulticaster

  • 该方法主要完成事件管理类的初始化,并加入一级缓存
  • 初始化ApplicationEventMulticaster事件,默认使用SimpleApplicationEventMulticaster事件

  • 9---onRefresh

  • onRefresh()方法是Spring预留给子类,用于初始化其他的Bean用的
  • 例:Spring中 AbstractApplicationContext onRefresh()的是没有做任何事情的
  • 而在Spring Boot中 ServletWebServerApplicationContext onRefresh()是有重写这个方法的

  • 其中super.onRefresh()为GenericWebApplicationContext onRefresh()

  • 这一步是初始化主题功能
  • 10---registerListeners

  • 方法主要将实现监听器接口(即ApplicationListener接口)的bean们注册到多播器中,即存储到applicationListenerBeans集合中
  • 代码分为三个步骤:
    • 1.注册硬编码方式的监听器
    • 2.注册配置文件的监听器
    • 3.发布需要进行发布的事件
  • 11---finishBeanFactoryInitialization

  • 该方法会实例化所有剩余的非懒加载单例 bean
  • 除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中
  • 代码步骤:
    • 1.初始化此上下文的转换服务
    • 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析
    • 3.初始化LoadTimeWeaverAware Bean实例对象
    • 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
    • 5.实例化所有剩余(非懒加载)单例对象
  • 12---finishRefresh

  • 完成上下文的刷新工作,包括初始化LifecycleProcessor,发布刷新完成事件等
  • 方法功能梳理:
    • 清理前面记录的类资源(因为已经有了BeanDefinition)
    • 初始化生命周期处理器,默认是DefaultLifecycleProcessor,并作为单例注册到容器
    • 触发DefaultLifecycleProcessor的onRefresh方法,简单来讲就是触发那些实现了Lifecycle的bean的start方法并将running状态设置为true
    • 发布事件ContextRefreshedEvent,标志着上下文刷新执行完毕
    • 注册ApplicationContext到LiveBeansView内部的applicationContexts中
    • 启动webserver,处理webserver的service与connector,并触发connector的start方法
    • 发布ServletWebServerInitializedEvent事件,标志着WebServer启动完毕
  • 小结

  • 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.finishBeanFactoryInitialization ---初始化单例Bean,执行Bean后处理器扩展
  • 12.finishRefresh ---准备生命周期管理器,发布ContextRefreshed事件

猜你喜欢

转载自blog.csdn.net/weixin_59624686/article/details/130977813
今日推荐