spring启动流程分析

简述一下spring的启动流程,省得每次都要翻看源码,流程图如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SpringApplication->SpringApplication#SpringApplication: 1-构造函数
SpringApplication#SpringApplication->SpringApplication#SpringApplication: 检测服务器类型
SpringApplication#SpringApplication->SpringApplication#SpringApplication: 2-META-INF/spring.factories
SpringApplication#SpringApplication->SpringApplication#SpringApplication: 3-实例化初始化器、监听器等
SpringApplication#SpringApplication->SpringApplication:
SpringApplication->SpringApplication#run:
SpringApplication#run->DefaultBootstrapContext: new DefaultBootstrapContext()
SpringApplication#run->SpringApplicationRunListener:starting
SpringApplication#run->SpringApplication#run:prepareEnvironment
SpringApplication#run->SpringApplicationRunListener:environmentPrepared
SpringApplication#run->AbstractApplicationContext:createApplicationContext
SpringApplication#run->SpringApplication#run:4-prepareContext
SpringApplication#run->ApplicationContextInitializer:5-initialize(ConfigurableApplicationContext applicationContext)
SpringApplication#run->SpringApplicationRunListener:contextPrepared
SpringApplication#run->SpringApplication#run:load
SpringApplication#run->SpringApplicationRunListener:contextLoaded
SpringApplication#run->AbstractApplicationContext:refresh
AbstractApplicationContext->AbstractApplicationContext: prepareBeanFactory
AbstractApplicationContext->AbstractApplicationContext: 6-invokeBeanFactoryPostProcessors
AbstractApplicationContext->AbstractApplicationContext: XXX一大堆东西,偷懒不写,改天补上
SpringApplication#run->SpringApplicationRunListener:started
SpringApplication#run->SpringApplication#run:7-callRunners

对于上图的解释:

  • 1-SpringApplication(ResourceLoader, Class<?>[])
  • 2-读取classpath下所有jar包内META-INF/spring.factories文件
  • 3-实例化:Bootstrapper、ApplicationContextInitializer、ApplicationListener
  • 5-这一步的最佳实践是:调用入参applicationContext的addBeanFactoryPostProcessor函数,也即注册自定义的BeanFactoryPostProcessor
  • 6-这一步中,会遍历AbstractApplicationContext内的列表:beanFactoryPostProcessors,并且当且仅当某一个BeanFactoryPostProcessor同时还是BeanDefinitionRegistryPostProcessor时,才会执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry,这两个接口的继承关系如图所示(beanFactoryPostProcessors列表的添加时机可以看上面第5步):

  • 7-先调用所有的ApplicationRunner,再调用所有的CommandLineRunner

至于spring bean生命周期,直接摘抄官网文档(来源:spring docs):

  1. BeanNameAware’s setBeanName
  2. BeanClassLoaderAware’s setBeanClassLoader
  3. BeanFactoryAware’s setBeanFactory
  4. EnvironmentAware’s setEnvironment
  5. EmbeddedValueResolverAware’s setEmbeddedValueResolver
  6. ResourceLoaderAware’s setResourceLoader (only applicable when running in an application context)
  7. ApplicationEventPublisherAware’s setApplicationEventPublisher (only applicable when running in an application context)
  8. MessageSourceAware’s setMessageSource (only applicable when running in an application context)
  9. ApplicationContextAware’s setApplicationContext (only applicable when running in an application context)
  10. ServletContextAware’s setServletContext (only applicable when running in a web application context)
  11. postProcessBeforeInitialization methods of BeanPostProcessors
  12. InitializingBean’s afterPropertiesSet
  13. a custom init-method definition
  14. postProcessAfterInitialization methods of BeanPostProcessors

当bean factory关闭时,如下生命周期函数将被调用:

  1. postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
  2. DisposableBean’s destroy
  3. a custom destroy-method definition