图解:SpringBoot Spring Dubbo 启动过程

OverView

Java程序员都应清楚Spring生命周期,这是Java程序员的基础知识。紧紧掌握这些知识点这不单单能够应付面试,更重要的是,能够更好的分析实际工做中的问题。
本文将把SpringBoot、Spring、Dubbo结合起来,分析他们的启动流程。整个过程大体会长下面这个样子。
屏幕快照 2020-01-01 下午10.26.07
下面,咱们就分别看看SpringBoot的启动过程。程序员

SpringBoot的启动过程

SpringBoot能够理解为Spring的启动程序,启动程序的入口方法为SpringApplication.run(),详细以下:
面试

A: 通知 Listener,start
B: 建立EnviromentEnviroment是整个应用的配置以及Profile的承载类
C: 建立容器
D: 初始化容器, ApplicationContext.refresh()即为容器初始化入口
E: 空方法
F: 通知 Listener,started
G: 通知 Listener,running
经过观察发现:SpringBoot.run()中代码步骤,大体能够概括总结为两种行为动做:app

  • SpringApplicationRunListeners调用(蓝色)
  • 建立和初始化容器(绿色)两部分
    因此我的以为SpringApplicationRunListeners表明了SpringBoot的生命周期,这个生命周期描述了SpringBoot的启动过程,如:建立初始化Enviroment,建立初始化容器

总结:SpringBoot的生命周期,以下图:post

Spring启动过程

在SpringBoot启动过程当中,会建立、刷新ApplicationContext。结合上面的流程后,以下图:

这里的refreshContext,就是Spring容器建立初始化的过程,下面咱们详细介绍一下此过程。spa

Spring中有一个类AbstractApplicationContext,全部类型的ApplicationContext,例如ClassPathXmlApplicationContextFileSystemXmlApplicationContext AnnotationConfigApplicationContext 都是继承此类。
AbstractApplicationContext 中有一个著名的方法refresh(),Spring容器的设计者们将容器启动过程抽象到了这个方法中,也就是AbstractApplication.refresh()方法中。 全部类型的ApplicationContext都会进入此方法。
debug

Dubbo的启动过程

Dubbo程序是以Spring Beans的形式存在于Spring容器中,随着Spring容器启动而启动。
对于Dubbo业务方来讲,主要有两个重要的Bean,ServiceBeanReferenceBean,他们各自会调用Service.export()Reference.get()来暴露服务以及引用远程服务。
在使用这两个Bean的时候,Dubbo的设计者为了让用户能够以Annotation的方式方便的使用,他们利用Spring的众多扩展点,在Spring容器启动过程当中,自动发现、注册、实例化了ServiceBeanReferenceBean设计

具体流程图以下:
3d

BeanDefinition的注册

EnableDubbo
若是咱们是使用Annotation方式使用Dubbo,那么会在SpringConfig类中添加@EnableDubbo注解,这个注解会利用@Import注解的BeanDefinition注册机制,向容器中注册DubboConfigBindingBeanPostProcessor ServiceAnnotationBeanPostProcessor ReferenceAnnotationBeanPostProcesser这三个重要的postProcessor来完成ServiceBeanReferenceBean的建立。代理

@Import注解是由下面的ConfigurationClassPostProcessor读取执行的。code

ConfigurationClassPostProcessor
Spring在容器的refresh()方法执行过程当中,当BeanFactory准备好后就会执行invokeBeanFactoryPostProcessors(BeanFactory),若是debug源码会发现刚开始候容器只有ConfigurationClassPostProcessor 这一个BeanFactoryPostProcessor,它的做用,按照源码的说法是:Bootstrapping processing of @Configuration 。源码注解大概意思是:它是第一个加载进容器并被执行的BeanFactoryPostProcessor,而后他做为Configuration引导过程,自动导入程序中的其余Configuration相关类。
原来,@Configuration @Import就是由它读取执行的。

ServiceAnnotationBeanPostProcessor
时机:

  1. ServiceAnnotationBeanPostProcessor是一个BeanFactoryPostProcessor在容器invokeBeanFactoryPostProcessors()过程当中,会被执行。

做用:以@Service做为过滤条件,扫描指定scanBasePackages,向容器注册ServiceBean。在refresh完成的时候,会向容器中发送ContextRefershEvent,ServiceBean实例会监听此事件,而后执行服务export过程。

扩展点:BeanFactoryPostProcessor

Bean初始化

ReferenceAnnotationBeanPostProcessor
时机:

  1. 在容器初始化完成后,会实例化容器中的单例非懒初始化Bean。
  2. 在实例化Bean之后,初始化Bean属性前会调用populateBean()方法,执行AnnotationInjectedBeanPostProcessor为注入依赖的属性。
  3. ReferenceAnnotationBeanPostProcessor就是继承自AnnotationInjectedBeanPostProcessor,此时它会随着一块儿执行。

动做:

  1. 加载扫描目录scanBasePackages下的类,找到@Reference所注解的字段,为其注入值。
  2. 注入的值为业务接口的动态代理类,动态代理(InvocationHandler)的逻辑是调用ReferenceBean.get()方法,建立真正的Invoker
  3. 因此最终注入了封装了远程调用逻辑的Invoker

Sping扩展点:BeanPostProcessor AnnotationInjectedBeanPostProcessor

DubboConfigBindingBeanPostProcessor
做用:为配置承载类:ApplicationConfigModuleConfig RegistryConfig ProtocolConfig等自动状态配置
Spring扩展点:BeanPostProcessor

相关文章
相关标签/搜索