版本:2.1.1.RELEASE
使用main方法启动Spring Boot应用:
1 | public static void main(String[] args) { |
进入SpringApplication类的run方法最终实现位置:
1 | public ConfigurableApplicationContext run(String... args) { |
run方法源码上注释了大概流程,接下来继续深入重点流程的源码。
流程4,获取Spring应用run方法的监听器集合并启动所有的监听器:
getRunListeners(String[] args) 方法源码:
1 | private SpringApplicationRunListeners getRunListeners(String[] args) { |
返回SpringApplicationRunListeners 实例,直接看构造方法的第二个参数的getSpringFactoriesInstances方法实现:
1 | private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, |
该方法第一个参数这里传入的是SpringApplicationRunListener 接口,会获取该接口所在类加载器下的“META-INF/spring.factories”属性文件
设置的接口实现org.springframework.boot.context.event.EventPublishingRunListener,然后调用该类的构造方法实例化:
1 | public EventPublishingRunListener(SpringApplication application, String[] args) { |
该类的主要作用是作为应用启动过程的事件发布监听器,可以看到构造方法中实例化了一个简单的应用事件多播器SimpleApplicationEventMulticaster 并遍历添加应用启动事件监听器。
流程4最后调用listeners.starting() 启动监听器,实现源码:
1 | @Override |
该方法多播一个ApplicationStartingEvent实例(应用启动事件),事件源是SpringApplication本身。
接下来就是解析事件类型并调用对应的事件监听器了,感兴趣的可以自己深入。深入之前需要对Spring事件机制有所了解,
推荐此文Spring事件机制。
流程6. 创建和配置环境:
prepareEnvironment(listeners, applicationArguments)方法实现:
1 | private ConfigurableEnvironment prepareEnvironment( |
其中,getOrCreateEnvironment() 方法实现:
1 | private ConfigurableEnvironment getOrCreateEnvironment() { |
流程9. 创建ApplicationContext:
createApplicationContext方法实现:
1 | protected ConfigurableApplicationContext createApplicationContext() { |
流程11. 准备应用上下文:
prepareContext方法实现:
1 | private void prepareContext(ConfigurableApplicationContext context, |
应用上下文对象准备好了,接下来就进行刷新上下文操作。
12. 刷新底层的ApplicationContext:
refreshContext方法实现:
1 | private void refreshContext(ConfigurableApplicationContext context) { |
进入到ServletWebServerApplicationContext类的refresh(context)方法实现:
1 | @Override |
发现是直接调用的父类AbstractApplicationContext的refresh方法实现:
1 | @Override |
第一点主要做了以下操作:
- 清除本地元数据缓存(如果有的话),删除所有缓存的类元数据。
- 设置其启动日期和活动标志以及执行任何属性源的初始化。
第二点主要做了以下操作:
- 将成员变量 refreshed 设为 true。
- 为 DefaultListableBeanFactory 指定一个用于序列化的id。
第三点主要做了以下操作:
- 配置工厂的标准上下文特征,例如上下文的类加载器和后置处理程序。
- 所有bean定义都已加载,但还没有实例化bean。
第四点主要做了以下操作:
- 注册特定应用上下文的后置处理器bean
- 扫描basePackage指定的包路径
- 注册被注解的类,例如@Configuration
第五点主要做了以下操作:
- 实例化并调用所有已注册的BeanFactoryPostProcessor bean,如果给定显式顺序,则遵循显式顺序
- 分别调用实现了BeanFactoryPostProcessor接口的bean。
第六点主要做了以下操作:
- 实例化并调用所有已注册的BeanPostProcessor bean,如果给定显式顺序,则遵循显式顺序
- 分别调用实现了BeanPostProcessor接口的bean。
第九点主要做了以下操作:
- 默认创建TomcatWebServer
- 初始化WebApplicationContext和SerlvetContext参数
第十一点完成BeanFactory的初始化并实例化剩余的单例bean:
finishBeanFactoryInitialization方法实现:
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
其中重点看最后一步preInstantiateSingletons方法的实现:
1 | @Override |
接下来看getBean(beanName)方法的底层实现,是直接调用doGetBean方法,返回指定bean的实例,该实例可以是共享的或独立的:
1 | protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, |
查看第二点getSingleton方法的实现:
1 | @Nullable |
几个重要对象说明:
- singletonObjects:单例bean对象的缓存,ConcurrentHashMap->{beanName:beanInstance}
- earlySingletonObjects: 早期的单例bean对象的缓存,HashMap->{beanName:beanInstance}
- singletonFactories:单例BeanFactory的缓存,HashMap->{beanName:beanFactory}, beanFactory->beanInstance
查看第四点getObjectForBeanInstance方法的实现:
1 | protected Object getObjectForBeanInstance( |
回到refresh方法的第十二点,最后完成上下文的刷新操作,调用LifecycleProcessor的onRefresh方法并且发布最终的ContextRefreshedEvent事件:
1 | protected void finishRefresh() { |
子类finishRefresh方法最后启动相应的WebServer并发布事件。
1 | @Override |
以上就是Spring Boot启动流程源码分析的完整内容,如果有问题欢迎提出!