SpringBoot启动流程
2022-05-06 17:25:56 33 举报
登录查看完整内容
hhhh
作者其他创作
大纲/内容
exceptionReporters = getSpringFactoriesInstances
ConfigurableApplicationContext#setEnvironment
配置上下文环境,包括添加删除或重新排序PropertySource和配置处于active的Profiles
AnnotatedGenericBeanDefinition#setPrimaryAnnotatedGenericBeanDefinition#setLazyInitAnnotatedGenericBeanDefinition#addQualifier
构造SpringApplication实例
AbstractApplicationContext#initPropertySources
AbstractApplicationContext
应用程序后处理
推断Application类型
在容器启动之前先实例化ApplicationListener接口的所有实现,这里都是从META-INF/spring.factories获取全限命名并实例化
SpringApplicationRunListeners#starting
回调SpringApplicationRunListeners接口的contextPrepared方法
设置应用程序事件的监听器接口
调用上下文环境预准备方法
SpringApplication#refreshContext
根据bean上的Conditional注解判断是否跳过该bean的解析注册,如果无条件注解则进行下一步
这里获取的是所有SpringApplicationRunListener的实现类,在原生的spring.factories里这里的实现是EventPublishingRunListener
ConditionEvaluator#shouldSkip
PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
SpringApplication#printBanner
SpringApplication#prepareEnvironment
SpringApplication#getRunListeners
处理beanDefintion共同的注解(Lazy,Primary,DependsOn,Role,Description)
将上下文环境绑定到SpringApplication
AnnotatedBeanDefinitionReader#register
BeanDefinitionLoader#load
校验上下文环境
configCandidates#sort
解析配置类
解析所有获取的配置资源
反射构建AnnotationConfigApplicationContext实例
AnnotatedBeanDefinitionReader#doRegisterBean
SpringApplication#prepareContext
3.优先排序调用实现PriorityOrdered接口4.其次排序调用实现Ordered接口5.最后排序调用剩下的接口
主要就是利用几个特殊的类的全限命名反射实例是否可以成功,如果抛异常则表明当前的Application Type不是该类型
SpringFactoriesLoader#loadSpringFactories
SpringApplicationRunListeners#contextPrepared
拿到META-INF/spring.factories下所有的预实例类的全限命名
配置环境
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
回调SpringApplicationRunListeners接口的contextLoaded方法
new SpringApplication
ConfigurationClassUtils#checkConfigurationClassCandidate
通过追溯程序的启动堆栈StackTraceElement,然后匹配方法为main的栈元素
new DefaultApplicationArguments
排序返回
这个bean工厂后置处理器是属于其中一个,专门解析配置类,解析如@Configuration等注解processConfigBeanDefinitions方法可以校验并构建一个配置类
调用SpringFactoriesLoader#loadSpringFactories方法获取所有的META-INF/spring.factories的所有预实例类的全限命名,再和当前的classType匹配返回,如果匹配不到则返回空集合。
这里获取的是所有SpringBootExceptionReporter的实现类
调用beanFactory的后置处理器
处理META-INF文件下的工作流程
准备上下文环境,如果不存在则新建并设置
刷新上下文预处理
设置应用程序上下文初始化回调接口
刷新应用程序上下文
SpringApplication#configureIgnoreBeanInfo
SpringApplication#run
推测应用程序的启动类
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
AbstractApplicationContext#obtainFreshBeanFactory
调用所有BeanFactoryPostProcessor接口的postProcessBeanFactory方法
在容器启动之前先实例化ApplicationContextInitializer接口的所有实现,这里都是从META-INF/spring.factories获取全限命名并实例化
调用BeanDefinitionCustomizer接口的customize方法
beanFactory.registerSingleton(\"springApplicationArguments\
GenericApplicationContext
判断一个类是否带有@Configuration注解
AbstractApplicationContext#getBeanFactory
1.迭代传参beanFactoryPostProcessors,如果其为BeanDefinitionRegistry则优先按照等级调用其postProcessBeanDefinitionRegistry方法,如果不是则调用其本身的postProcessBeanFactory方法
如果有多个则参考根据@Order注解排序
根据条件是否实则Primary,LazyInit,Qualifier
如果该后置处理器属于BeanDefinitionRegistryPostProcessor则事先调用该接口的postProcessBeanDefinitionRegistry方法
AbstractApplicationContext#getEnvironment#validateRequiredProperties
构建父类AbstractApplicationContext
AbstractApplicationContext#postProcessBeanFactory
BeanDefinitionLoader有多个加载资源的方法,这里选择的是注解方式的
实例化ApplicationArguments对象
SpringApplication#deduceMainApplicationClass
WebApplicationType#deduceFromClasspath
根据先前推测的applicationType实例上下文环境
BeanDefinitionReaderUtils#registerBeanDefinition
是
2.获取beanFactory剩下的未调用过方法的所有BeanFactoryPostProcessor接口
刷新内部beanFactory,留给子类实现
AnnotationAwareOrderComparator#sort(instances)
SpringApplicationRunListeners#environmentPrepared
设置上下文环境
ScopeMetadataResolver#resolveScopeMetadata
打印banner
获取内部的beanfactory
配置忽视beanInfo
根据拿到的所有类的全限命名迭代反射实例然后返回
BeanFactory的前置处理,包括配置beanfactory的classloader和后置处理器等,忽视特定接口的配置
AbstractApplicationContext#prepareRefresh
解析ScopeMetadata
注册钩子方法
上下文刷新前处理
回调SpringApplicationRunListeners接口的environmentPrepared方法
启动SpringApplicationRunListener
ConfigurationClassPostProcessor#processConfigBeanDefinitions
构建父类GenericApplicationContext,该父类内部持有的DefaultListableBeanFactory为最终的IOC容器
AnnotationConfigApplicationContext
SpringApplication#bindToSpringApplication
beanFactory instanceof BeanDefinitionRegistry
初始化PropertySources,可以替换一些placeholder,留给子类实现
从beanFactory获取剩下的BeanDefinitionRegistryPostProcessor并按照排序调用其postProcessBeanDefinitionRegistry方法
AbstractApplicationContext#invokeBeanFactoryPostProcessors
AbstractApplicationContext#refresh
SpringApplicationRunListeners#contextLoaded
从beanFactory获取实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor并按照排序调用其postProcessBeanDefinitionRegistry方法
SpringApplication#load
调用BeanDefinitionLoader的load方法
获取BeanFactory
SpringApplication#createApplicationContext
SpringApplication#applyInitializers
BeanDefinitionCustomizer#customize
SpringApplication#postProcessApplicationContext
刷新容器
从beanFactory获取实现Ordered接口的BeanDefinitionRegistryPostProcessor并按照排序调用其postProcessBeanDefinitionRegistry方法
这里的传参type就是需要被事先反射实例的class type
N
上下文初始化之前回调ApplicationContextInitializer接口的initialize方法
ConfigurationClassParser#processConfigurationClass
SpringApplication#getSpringFactoriesInstances(Class<T> type)
BeanFactory的后置处理
AbstractApplicationContext#refreshBeanFactory
上下文环境预前准备
如果需要将用户自定义环境做适配
ConfigurationPropertySources#attach(environment)
AbstractApplicationContext#prepareBeanFactory
SpringApplication#setListeners
实例化异常打印类
ConfigurationClassParser#parse
SpringApplication#configureEnvironment
SpringApplication#setInitializers
注册beanDefinition
构造成功之后调用SpringApplication的run方法,这个run方法是实例方法不是静态的
SpringApplication#getOrCreateEnvironment
做几个特殊的处理:注册特殊的bean;配置是否允许循环依赖;配置是否允许bean工厂懒加载后置处理器
AnnotationConfigUtils#processCommonDefinitionAnnotations
在前面获取的所有SpringApplicationRunListener的实现,然后回调starting接口
收藏
0 条评论
回复 删除
下一页