SpringBoot 启动流程
代码语言:javascript复制public static ConfigurableApplicationContext run(Class<?>[]primarySources,String[]args){
// 两件事:1、初始化SpringApplication 2、执行run方法
return new SpringApplication(primarySources).run(args);
}
初始化SpringApplication
- 读取
SpringBootMyTestApplication
类的所有信息 - 推断当前SpringBoot应用类型是
WebApplicationType.SERVLET
还是WebApplicationType.REACTIVE
- 初始化
classpath
下META-INF/spring.factories
中已配置得ApplicationContextInitializer
- 初始化
classpath
下所有已配置得ApplicationListener
- 根据调用栈,推断出 main 方法得类名
如何根据调用栈判断得? 还没找到判断方式,源码太难理解
执行run方法
- 初始化
classpath
下META-INF/spring.factories
中已配置得SpringApplicationRunListener
- 构建应用上下文
- 初始化上下文
创建
AnnotationConfigServletWebServerApplicationContext
Context上下文时,IOC容器
也进行了创建,IOC容器
的本质就是org.springframework.beans.factory.support.DefalutListableBeanFactory
- 刷新应用上下文的准备阶段
注册bean的流程
Spring容器在启动的时候,会将类解析成Spring内部的beanDefinition,并将beanDefinition存储到org.springframework.beans.factory.support.DefalutListableBeanFactory的Map中
((DefaultListableBeanFactory)((AnnotationConfigServletWebServerApplicationContext)context).beanFactory).beanDefinitionMap
下面就是一个启动类Bean的详细信息
springBootMyTestApplication -> {AnnotatedGenericBeanDefinition@4533} "Generic bean: class [com.example.springbootmytest.SpringBootMyTestApplication]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null"
SpringBoot自动化配置原理?
- 刷新上下文(
Ioc
容器初始化过程的三个步骤)
(1)、Resource定位
(2)、BeanDefinition的载入
(3)、注册BeanDefinition
如何解析包含 @ComponentScan @Import 等等?
刷新BeanFactory
,获取ConfigurableListableBeanFactory
注册Bean
的工厂
org.springframework.beans.factory.config.ConfigurableListableBeanFactory.java
postProcessBeanDefinitionRegistry
判断ConfigurableListableBeanFactory
是否是BeanDefinitionRegistry
的子类,ConfigurableListableBeanFactory
强转成BeanDefinitionRegistry
从BeanDefinitionRegistry
中获取BeanDefinition
,将BeanDefinitionRegistry
获取到的BeanDefinition
加载到List<BeanDefinitionHolder>
中
判断BeanDefinitionRegistry
是否是SingletonBeanRegistry
的子类 -> 将 BeanDefinitionRegistry
强转成SingletonBeanRegistry
随后将List<BeanDefinitionHolder>
转换成Set<BeanDefinitionHolder>
解析Set<BeanDefinitionHolder>
,判断BeanDefinitionHolder
是否是AnnotatedBeanDefinition
的子类 -> 将 BeanDefinitionHolder
强转成AnnotatedBeanDefinition
,并获取Metadata
,即为AnnotationMetadata
将AnnotationMetadata
初始化为ConfigurationClass
,从ConfigurationClass
获取的Metadata
作为SourceClass
去解析
org.springframework.context.annotation.ConfigurationClassParser
的doProcessConfigurationClass
判断类中是否包含@Component
、@PropertySources
、@ComponentScan
、@Import
等
本次学习的
SpringBoot
源码版本为Spring-Boot-2.2.9.RELEASE
具体代码阅读笔记可以参考:https://github.com/lzmvlog/Spring-Boot-2.2.9.RELEASE/tree/main/spring-boot-mytest