springboot启动原理

开头语:springboot利用spring提供的功能,对spring的开发环境进行模版式的初始化,使得编程人员省去了手工编写spring初始化流程

一:Spring功能提示:

1.1:spring通过扫描将有关bean的定义组装成对象,然后利用该配置对象,在合适的时候根据配置对象生成相应的bean对象。spring不论是component-scan标签,还是@ComponentScan注解。它们扫描或解析的bean只能是Spring内部所定义的,比如@Component、@Service、@Controller或@Repository。用户自定义的注解不在扫描范围之内

二:SpringBoot功能原理分析

2.1:功能相关的类

SpringBoot把配置文件的加载封装成了PropertySourceLoader接口,该接口的实现有:

PropertiesPropertySourceLoader支持从xml或properties格式的文件中加载数据。

YamlPropertySourceLoader支持从yml或者yaml格式的文件中加载数据。

2.2:springboot之配置Environment环境的构造过程

2.2.1:Environment的构造

在Spring容器构造之前调用,创建环境信息。

Environment接口是Spring对当前程序运行期间的环境的封装。主要提供了两大功能:profile和property(父接口PropertyResolver提供)。目前主要有StandardEnvironment、StandardServletEnvironment和MockEnvironment3种实现,分别代表普通程序、Web程序以及测试程序的环境

SpringApplication启动的时候会构造环境信息Environment,如果是web环境,创建StandardServletEnvironment,否则,创建StandardEnvironment。

这两种环境创建的时候都会在Environment内部的propertySources属性中加入一些PropertySource。

比如属性属性的配置信息封装成MapPropertySource,系统环境配置信息封装成SystemEnvironmentPropertySource等。

这些PropertySource集合存在在环境信息中,从环境信息中读取配置的话会遍历这些PropertySource并找到相对应的配置和值。Environment构造完成之后会读取springboot相应的配置文件,从3个角度去查找:目录、文件名和profile。这3个角度有默认值,可以进行覆盖。

springboot相关的配置文件读取完成之后会被封装成PropertySource并添加到环境信息中。

2.2.2:Environment属性配置

SpringBoot内部规定了一套配置和配置属性类映射规则,可以使用@ConfigurationProperties注解配合前缀属性完成属性类的读取;再通过@EnableConfigurationProperties注解设置配置类就可以把这个配置类注入进来。

由于这个配置类是被注入进来的,所以它肯定在Spring容器中存在;

这是因为在ConfigurationPropertiesBeanRegistrar内部会注册配置类到Spring容器中,这个配置类的实例化过程在ConfigurationPropertiesBindingPostProcessor这个BeanPostProcessor完成,它会在实例化bean之前会判断bean是否被@ConfigurationProperties注解修饰,如果有,使用PropertiesConfigurationFactory从环境信息Environment中进行值的绑定。

这个ConfigurationPropertiesBeanRegistrar是在使用@EnableConfigurationProperties注解的时候被创建的(通过EnableConfigurationPropertiesImportSelector)。配置类内部属性的绑定成功与否是通过环境信息Environment中的属性源PropertySource决定的。

2.3:springboot启动过程

SpringBoot启动的时候,不论调用什么方法,都会构造一个SpringApplication的实例,然后调用这个实例的run方法,这样就表示启动SpringBoot。

2.3.1:在run方法调用之前,也就是构造SpringApplication的时候会进行初始化的工作,初始化的时候会做以下几件事:

  1. 把参数sources设置到SpringApplication属性中,这个sources可以是任何类型的参数。本文的例子中这个sources就是MyApplication的class对象
  2. 判断是否是web程序,并设置到webEnvironment这个boolean属性中
  3. 找出所有的初始化器,默认有5个,设置到initializers属性中
  4. 找出所有的应用程序监听器,默认有9个,设置到listeners属性中
  5. 找出运行的主类(main class)

2.3.2:SpringApplication构造完成之后调用run方法,启动SpringApplication,run方法执行的时候会做以下几件事:

  1. 构造一个StopWatch,观察SpringApplication的执行
  2. 找出所有的SpringApplicationRunListener并封装到SpringApplicationRunListeners中,用于监听run方法的执行。监听的过程中会封装成事件并广播出去让初始化过程中产生的应用程序监听器进行监听
  3. 构造Spring容器(ApplicationContext),并返回
    3.1 创建Spring容器的判断是否是web环境,是的话构造AnnotationConfigEmbeddedWebApplicationContext,否则构造AnnotationConfigApplicationContext
    3.2 初始化过程中产生的初始化器在这个时候开始工作
    3.3 Spring容器的刷新(完成bean的解析、各种processor接口的执行、条件注解的解析等等)
  4. 从Spring容器中找出ApplicationRunner和CommandLineRunner接口的实现类并排序后依次执行

 

 



 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值