SpringBoot大致启动流程
以main方法为入口进入:
↓
↓
↓
主线流程到此结束,接下来重点看 6,7,8这三个方法中详细的代码流程,首先是prepareContext进行上下文预处理:
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context.setEnvironment(environment);//为上下文设置Environment this.postProcessApplicationContext(context); this.applyInitializers(context); listeners.contextPrepared(context); if (this.logStartupInfo) { this.logStartupInfo(context.getParent() == null); this.logStartupProfileInfo(context); } ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); beanFactory.registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { beanFactory.registerSingleton("springBootBanner", printedBanner);//注册banner单例 } if (beanFactory instanceof DefaultListableBeanFactory) { ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.lazyInitialization) { context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor()); } Set<Object> sources = this.getAllSources(); Assert.notEmpty(sources, "Sources must not be empty");//断言 this.load(context, sources.toArray(new Object[0])); listeners.contextLoaded(context); }
之后是refreshContext进行上下文更新:
1 private void refreshContext(ConfigurableApplicationContext context) { 2 this.refresh((ApplicationContext)context); 3 if (this.registerShutdownHook) { 4 try { 5 context.registerShutdownHook(); 6 } catch (AccessControlException var3) { 7 } 8 } 9 10 }
↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public void refresh() throws BeansException, IllegalStateException { synchronized ( this .startupShutdownMonitor) { //使用synchronized对象锁锁住整个方法,strtupShutdownMonitor为Object实例对象 this .prepareRefresh(); //更新前的数据准备,startupDate设置为当前时间,closed设为false,active设为true ConfigurableListableBeanFactory beanFactory = this .obtainFreshBeanFactory(); this .prepareBeanFactory(beanFactory); //进行大量赋值,最终以执行resetCommonCaches结束 try { this .postProcessBeanFactory(beanFactory); this .invokeBeanFactoryPostProcessors(beanFactory); this .registerBeanPostProcessors(beanFactory); this .initMessageSource(); this .initApplicationEventMulticaster(); this .onRefresh(); this .registerListeners(); this .finishBeanFactoryInitialization(beanFactory); this .finishRefresh(); } catch (BeansException var9) { if ( this .logger.isWarnEnabled()) { this .logger.warn( "Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this .destroyBeans(); this .cancelRefresh(var9); throw var9; } finally { this .resetCommonCaches(); } } } |
refresh()方法运行是有规律的,总体流程是prepareRefresh()->onRefresh()->finishRefresh(),接下来分别看看这三个方法的具体代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | protected void prepareRefresh() { this .startupDate = System.currentTimeMillis(); //记录开始时间 this .closed.set( false ); //打开更新 this .active.set( true ); //设置为可更新状态 if ( this .logger.isDebugEnabled()) { if ( this .logger.isTraceEnabled()) { this .logger.trace( "Refreshing " + this ); } else { this .logger.debug( "Refreshing " + this .getDisplayName()); } } this .initPropertySources(); this .getEnvironment().validateRequiredProperties(); if ( this .earlyApplicationListeners == null ) { this .earlyApplicationListeners = new LinkedHashSet( this .applicationListeners); } else { this .applicationListeners.clear(); this .applicationListeners.addAll( this .earlyApplicationListeners); } this .earlyApplicationEvents = new LinkedHashSet(); } |
1 2 | protected void onRefresh() throws BeansException { //空壳方法,看似是一个空方法,但是对于提高系统扩展性有很重要的地位,如它的实现类中有一个createWebServer()方法,这个方法提供了tomcat/netty等的实现源码 } |
1 2 3 4 5 6 7 | protected void finishRefresh() { this .clearResourceCaches(); //清空资源缓存 this .initLifecycleProcessor(); //重置lifecycle执行器 this .getLifecycleProcessor().onRefresh(); this .publishEvent((ApplicationEvent)( new ContextRefreshedEvent( this ))); //发布上下文更新成功事件 LiveBeansView.registerApplicationContext( this ); } |
最後是afterRefresh方法:
1 protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) { 2 }
afterRefresh方法结束,只有一个空壳方法在这里,应该可以进行自定义拓展;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix