最近查看Spring代码的一些思考所得。因为对于启动过程进行了一部分自我总结,希望不会给大家带来困扰,还请大家勘误,指正。
spring-boot 启动顺序:
1:被@SpringBootApplication注解的启动类的main方法
2:SpringApplicationBuilder.init<>();
3:SpringApplication.init<>();
4:springApplication.getSpringFactoriesInstance();在meta-info/路径下查找springfactories,初始化ApplicationListener,ApplicationContextInitializer
5:SpringApplication发布ApplicationStartingEvent事件:
6:SpringApplication.run();
7:SpringApplication.prepareEnvironment();
8:监听到SpringApplication发布的ApplicationEnvironmentPreparedEvent 事件
9:ConfigFileApplicationListener监听到ApplicationEvnvironmentPreparedEvent之后初始化EnvironmentPostProcessor,自定义environment
10:SpringApplication.prepareContext(),此时调用初始化过的ApplicationContextInitialize;自定义修改ApplicationContext;
11:监听到SpingApplication发布的 ApplicationPreparedEvent事件;
12: refresh root of context hierarchy applicationContext 是 AnnotationConfigServletWebServerApplicationContext
13:SpringApplication.refreshContext(),调用 WebServerApplicationContext.refresh()方法,这个时候会创建特殊的bean,invokeBeanFactoryPostProcessors(),registryBeanPostProcessors()等
14:初始化消息源
15:createWebServer;;;创建tomcat的servlet部分,并且会加载一些bean
16:root of context hierarchy 刷新时,会调用finishBeanFactoryInitialization()方法,初始化所有non-lazy的bean,这个时候初始化所有的@component并且调用beanpostProcessor,如果有特殊的bean继承了SmartInitializingSingleton,例如子Context,会执行afterSingletonsInstantiated()方法
17:子context刷新完之后,监听到子context的ContextRefreshedEvent事件
18:父context刷新完,监听到父context的ContextRefreshedEvent事件
19:监听到tomcat融资的ServletWebServerInitializedEvent事件
20:监听到Spring Application的ApplicationStartedEvent事件
21:监听到SpringApplication的ApplicationReadyEvent事件
22:关闭spring
22.1:监听到root of context hierarchy AnnotationConfigServletWebServerApplicationContext发布的ContextClosedEvent 事件
22.2:监听到子AnnotationConfigServletWebServerApplicationContext 发布的contextClosedEvent事件
其实上面的每个过程都很复杂,而且有很多步骤是我们个性化自己项目框架的重要扩展点。
比如我们经常看到的几个接口:
1:ApplicationListener,可以监听所有spring的事件
2:ApplicationContextInitializer,可以自定义修改root of context hierarchy的AnnotationConfigServletWebServerApplicationContext
3:BeanFactoryPostProcessor,bean工厂自定义
4:BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcesser,都可以在beanDefinition被加载完之后修改beandefinition的属性。
5:BeanPostProcessor的接口可以帮助我们在Bean初始化之后进行一些特殊处理,比如切面变成或者是动态代理。
6:InitializingBean,在bean创建之后,属性被注入之后调用,这一个bean生命周期之中可以被改动的最后一个接口。
其余的接口我不是经常看到,所以也不敢乱讲,但是我希望大家能从整体上了解spring,知道spring的扩展点,然后从这几个接口出发,了解体会自己项目中的代码框架