图解: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()中代码步骤,大致可以归纳总结为两种行为动作:

  • SpringApplicationRunListeners调用(蓝色)
  • 创建和初始化容器(绿色)两部分
    所以个人觉得SpringApplicationRunListeners代表了SpringBoot的生命周期,这个生命周期描述了SpringBoot的启动过程,如:创建初始化Enviroment,创建初始化容器

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

Spring启动过程

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

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

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

Dubbo的启动过程

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

具体流程图如下:

BeanDefinition的注册

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

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

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

猜你喜欢

转载自www.cnblogs.com/xuerge/p/jie-hespring-tu-jiedubbo-qi-dong-guo-cheng.html